1 // The template and inlines for the -*- C++ -*- numeric_limits classes.
3 // Copyright (C) 2000-2001 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 // Note: this is not a conforming implementation.
31 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
38 /** @file limits_generic.h
43 #ifndef _CPP_NUMERIC_LIMITS
44 #define _CPP_NUMERIC_LIMITS 1
46 #pragma GCC system_header
48 #include <bits/c++config.h>
49 #include <bits/std_cfloat.h>
50 #include <bits/std_climits.h>
51 #if defined( _GLIBCPP_USE_WCHAR_T)
52 #include <bits/std_cwchar.h>
57 /// Rounding style determines the behavior of floating-point calculations.
58 enum float_round_style
{
59 round_indeterminate
= -1,
60 round_toward_zero
= 0,
62 round_toward_infinity
= 2,
63 round_toward_neg_infinity
= 3
66 /// This enum signals whether a type has denormalization.
67 enum float_denorm_style
{
68 denorm_indeterminate
= -1,
74 * [18.2.1]/1: "The numeric_limits component provides a C++ program
75 * with information about various properties of the implementation's
76 * representation of the fundamental types." All of the standard
77 * fundamental types have specializations of this class template.
78 * @brief Properties of fundamental types on a per-platform basis.
80 template<typename _T
> struct numeric_limits
{
81 static const bool is_specialized
= false;
83 static _T
min() throw() { return static_cast<_T
>(0); }
84 static _T
max() throw() { return static_cast<_T
>(0); }
86 static const int digits
= 0;
87 static const int digits10
= 0;
88 static const bool is_signed
= false;
89 static const bool is_integer
= false;
90 static const bool is_exact
= false;
91 static const int radix
= 0;
93 static _T
epsilon() throw() { return static_cast<_T
>(0); }
94 static _T
round_error() throw() { return static_cast<_T
>(0); }
96 static const int min_exponent
= 0;
97 static const int min_exponent10
= 0;
98 static const int max_exponent
= 0;
99 static const int max_exponent10
= 0;
101 static const bool has_infinity
= false;
102 static const bool has_quiet_NaN
= false;
103 static const bool has_signaling_NaN
= false;
104 static const float_denorm_style has_denorm
= denorm_absent
;
105 static const bool has_denorm_loss
= false;
107 static _T
infinity() throw() { return static_cast<_T
>(0); }
108 static _T
quiet_NaN() throw() { return static_cast<_T
>(0); }
109 static _T
signaling_NaN() throw() { return static_cast<_T
>(0); }
110 static _T
denorm_min() throw() { return static_cast<_T
>(0); }
112 static const bool is_iec559
= false;
113 static const bool is_bounded
= false;
114 static const bool is_modulo
= false;
116 static const bool traps
= false;
117 static const bool tinyness_before
= false;
118 static const float_round_style round_style
= round_toward_zero
;
121 template<typename _T
> _T
__limits_infinity();
122 template<typename _T
> _T
__limits_quiet_NaN();
123 template<typename _T
> _T
__limits_signaling_NaN();
124 template<typename _T
> _T
__limits_denorm_min();
126 template<> struct numeric_limits
<bool> {
127 static const bool is_specialized
= true;
129 static bool min() throw()
131 static bool max() throw()
134 static const int digits
= 1;
135 static const int digits10
= 0;
136 static const bool is_signed
= false;
137 static const bool is_integer
= true;
138 static const bool is_exact
= true;
139 static const int radix
= 2;
140 static bool epsilon() throw()
142 static bool round_error() throw()
145 static const int min_exponent
= 0;
146 static const int min_exponent10
= 0;
147 static const int max_exponent
= 0;
148 static const int max_exponent10
= 0;
150 static const bool has_infinity
= false;
151 static const bool has_quiet_NaN
= false;
152 static const bool has_signaling_NaN
= false;
153 static const float_denorm_style has_denorm
= denorm_absent
;
154 static const bool has_denorm_loss
= false;
156 static bool infinity() throw()
157 { return static_cast<bool>(0); }
158 static bool quiet_NaN() throw()
159 { return static_cast<bool>(0); }
160 static bool signaling_NaN() throw()
161 { return static_cast<bool>(0); }
162 static bool denorm_min() throw()
163 { return static_cast<bool>(0); }
165 static const bool is_iec559
= false;
166 static const bool is_bounded
= true;
167 static const bool is_modulo
= false;
169 static const bool traps
= false;
170 static const bool tinyness_before
= false;
171 static const float_round_style round_style
= round_toward_zero
;
174 template<> struct numeric_limits
<char> {
175 static const bool is_specialized
= true;
177 static char min() throw()
179 static char max() throw()
182 static const int digits
= 7;
183 static const int digits10
= 2;
184 static const bool is_signed
= true;
185 static const bool is_integer
= true;
186 static const bool is_exact
= true;
187 static const int radix
= 2;
188 static char epsilon() throw()
190 static char round_error() throw()
193 static const int min_exponent
= 0;
194 static const int min_exponent10
= 0;
195 static const int max_exponent
= 0;
196 static const int max_exponent10
= 0;
198 static const bool has_infinity
= false;
199 static const bool has_quiet_NaN
= false;
200 static const bool has_signaling_NaN
= false;
201 static const float_denorm_style has_denorm
= denorm_absent
;
202 static const bool has_denorm_loss
= false;
204 static char infinity() throw()
205 { return static_cast<char>(0); }
206 static char quiet_NaN() throw()
207 { return static_cast<char>(0); }
208 static char signaling_NaN() throw()
209 { return static_cast<char>(0); }
210 static char denorm_min() throw()
211 { return static_cast<char>(0); }
213 static const bool is_iec559
= false;
214 static const bool is_bounded
= true;
215 static const bool is_modulo
= false;
217 static const bool traps
= false;
218 static const bool tinyness_before
= false;
219 static const float_round_style round_style
= round_toward_zero
;
222 template<> struct numeric_limits
<signed char> {
223 static const bool is_specialized
= true;
225 static signed char min() throw()
226 { return SCHAR_MIN
; }
227 static signed char max() throw()
228 { return SCHAR_MAX
; }
230 static const int digits
= 7;
231 static const int digits10
= 2;
232 static const bool is_signed
= true;
233 static const bool is_integer
= true;
234 static const bool is_exact
= true;
235 static const int radix
= 2;
236 static signed char epsilon() throw()
238 static signed char round_error() throw()
241 static const int min_exponent
= 0;
242 static const int min_exponent10
= 0;
243 static const int max_exponent
= 0;
244 static const int max_exponent10
= 0;
246 static const bool has_infinity
= false;
247 static const bool has_quiet_NaN
= false;
248 static const bool has_signaling_NaN
= false;
249 static const float_denorm_style has_denorm
= denorm_absent
;
250 static const bool has_denorm_loss
= false;
252 static signed char infinity() throw()
253 { return static_cast<signed char>(0); }
254 static signed char quiet_NaN() throw()
255 { return static_cast<signed char>(0); }
256 static signed char signaling_NaN() throw()
257 { return static_cast<signed char>(0); }
258 static signed char denorm_min() throw()
259 { return static_cast<signed char>(0); }
261 static const bool is_iec559
= false;
262 static const bool is_bounded
= true;
263 static const bool is_modulo
= false;
265 static const bool traps
= false;
266 static const bool tinyness_before
= false;
267 static const float_round_style round_style
= round_toward_zero
;
270 template<> struct numeric_limits
<unsigned char> {
271 static const bool is_specialized
= true;
273 static unsigned char min() throw()
275 static unsigned char max() throw()
276 { return UCHAR_MAX
; }
278 static const int digits
= 8;
279 static const int digits10
= 2;
280 static const bool is_signed
= false;
281 static const bool is_integer
= true;
282 static const bool is_exact
= true;
283 static const int radix
= 2;
284 static unsigned char epsilon() throw()
286 static unsigned char round_error() throw()
289 static const int min_exponent
= 0;
290 static const int min_exponent10
= 0;
291 static const int max_exponent
= 0;
292 static const int max_exponent10
= 0;
294 static const bool has_infinity
= false;
295 static const bool has_quiet_NaN
= false;
296 static const bool has_signaling_NaN
= false;
297 static const float_denorm_style has_denorm
= denorm_absent
;
298 static const bool has_denorm_loss
= false;
300 static unsigned char infinity() throw()
301 { return static_cast<unsigned char>(0); }
302 static unsigned char quiet_NaN() throw()
303 { return static_cast<unsigned char>(0); }
304 static unsigned char signaling_NaN() throw()
305 { return static_cast<unsigned char>(0); }
306 static unsigned char denorm_min() throw()
307 { return static_cast<unsigned char>(0); }
309 static const bool is_iec559
= false;
310 static const bool is_bounded
= true;
311 static const bool is_modulo
= true;
313 static const bool traps
= true;
314 static const bool tinyness_before
= false;
315 static const float_round_style round_style
= round_toward_zero
;
318 #if defined( _GLIBCPP_USE_WCHAR_T)
319 template<> struct numeric_limits
<wchar_t> {
320 static const bool is_specialized
= true;
322 static wchar_t min() throw()
323 { return WCHAR_MIN
; }
324 static wchar_t max() throw()
325 { return WCHAR_MAX
; }
327 static const int digits
= 31;
328 static const int digits10
= 9;
329 static const bool is_signed
= true;
330 static const bool is_integer
= true;
331 static const bool is_exact
= true;
332 static const int radix
= 2;
333 static wchar_t epsilon() throw()
335 static wchar_t round_error() throw()
338 static const int min_exponent
= 0;
339 static const int min_exponent10
= 0;
340 static const int max_exponent
= 0;
341 static const int max_exponent10
= 0;
343 static const bool has_infinity
= false;
344 static const bool has_quiet_NaN
= false;
345 static const bool has_signaling_NaN
= false;
346 static const float_denorm_style has_denorm
= denorm_absent
;
347 static const bool has_denorm_loss
= false;
349 static wchar_t infinity() throw()
350 { return static_cast<wchar_t>(0); }
351 static wchar_t quiet_NaN() throw()
352 { return static_cast<wchar_t>(0); }
353 static wchar_t signaling_NaN() throw()
354 { return static_cast<wchar_t>(0); }
355 static wchar_t denorm_min() throw()
356 { return static_cast<wchar_t>(0); }
358 static const bool is_iec559
= false;
359 static const bool is_bounded
= true;
360 static const bool is_modulo
= false;
362 static const bool traps
= false;
363 static const bool tinyness_before
= false;
364 static const float_round_style round_style
= round_toward_zero
;
368 template<> struct numeric_limits
<short> {
369 static const bool is_specialized
= true;
371 static short min() throw()
373 static short max() throw()
376 static const int digits
= 15;
377 static const int digits10
= 4;
378 static const bool is_signed
= true;
379 static const bool is_integer
= true;
380 static const bool is_exact
= true;
381 static const int radix
= 2;
382 static short epsilon() throw()
384 static short round_error() throw()
387 static const int min_exponent
= 0;
388 static const int min_exponent10
= 0;
389 static const int max_exponent
= 0;
390 static const int max_exponent10
= 0;
392 static const bool has_infinity
= false;
393 static const bool has_quiet_NaN
= false;
394 static const bool has_signaling_NaN
= false;
395 static const float_denorm_style has_denorm
= denorm_absent
;
396 static const bool has_denorm_loss
= false;
398 static short infinity() throw()
399 { return static_cast<short>(0); }
400 static short quiet_NaN() throw()
401 { return static_cast<short>(0); }
402 static short signaling_NaN() throw()
403 { return static_cast<short>(0); }
404 static short denorm_min() throw()
405 { return static_cast<short>(0); }
407 static const bool is_iec559
= false;
408 static const bool is_bounded
= true;
409 static const bool is_modulo
= false;
411 static const bool traps
= false;
412 static const bool tinyness_before
= false;
413 static const float_round_style round_style
= round_toward_zero
;
416 template<> struct numeric_limits
<unsigned short> {
417 static const bool is_specialized
= true;
419 static unsigned short min() throw()
421 static unsigned short max() throw()
422 { return USHRT_MAX
; }
424 static const int digits
= 16;
425 static const int digits10
= 4;
426 static const bool is_signed
= false;
427 static const bool is_integer
= true;
428 static const bool is_exact
= true;
429 static const int radix
= 2;
430 static unsigned short epsilon() throw()
432 static unsigned short round_error() throw()
435 static const int min_exponent
= 0;
436 static const int min_exponent10
= 0;
437 static const int max_exponent
= 0;
438 static const int max_exponent10
= 0;
440 static const bool has_infinity
= false;
441 static const bool has_quiet_NaN
= false;
442 static const bool has_signaling_NaN
= false;
443 static const float_denorm_style has_denorm
= denorm_absent
;
444 static const bool has_denorm_loss
= false;
446 static unsigned short infinity() throw()
447 { return static_cast<unsigned short>(0); }
448 static unsigned short quiet_NaN() throw()
449 { return static_cast<unsigned short>(0); }
450 static unsigned short signaling_NaN() throw()
451 { return static_cast<unsigned short>(0); }
452 static unsigned short denorm_min() throw()
453 { return static_cast<unsigned short>(0); }
455 static const bool is_iec559
= false;
456 static const bool is_bounded
= true;
457 static const bool is_modulo
= true;
459 static const bool traps
= true;
460 static const bool tinyness_before
= false;
461 static const float_round_style round_style
= round_toward_zero
;
464 template<> struct numeric_limits
<int> {
465 static const bool is_specialized
= true;
467 static int min() throw()
469 static int max() throw()
472 static const int digits
= 31;
473 static const int digits10
= 9;
474 static const bool is_signed
= true;
475 static const bool is_integer
= true;
476 static const bool is_exact
= true;
477 static const int radix
= 2;
478 static int epsilon() throw()
480 static int round_error() throw()
483 static const int min_exponent
= 0;
484 static const int min_exponent10
= 0;
485 static const int max_exponent
= 0;
486 static const int max_exponent10
= 0;
488 static const bool has_infinity
= false;
489 static const bool has_quiet_NaN
= false;
490 static const bool has_signaling_NaN
= false;
491 static const float_denorm_style has_denorm
= denorm_absent
;
492 static const bool has_denorm_loss
= false;
494 static int infinity() throw()
495 { return static_cast<int>(0); }
496 static int quiet_NaN() throw()
497 { return static_cast<int>(0); }
498 static int signaling_NaN() throw()
499 { return static_cast<int>(0); }
500 static int denorm_min() throw()
501 { return static_cast<int>(0); }
503 static const bool is_iec559
= true;
504 static const bool is_bounded
= true;
505 static const bool is_modulo
= false;
507 static const bool traps
= false;
508 static const bool tinyness_before
= false;
509 static const float_round_style round_style
= round_toward_zero
;
512 template<> struct numeric_limits
<unsigned int> {
513 static const bool is_specialized
= true;
515 static unsigned int min() throw()
517 static unsigned int max() throw()
520 static const int digits
= 32;
521 static const int digits10
= 9;
522 static const bool is_signed
= false;
523 static const bool is_integer
= true;
524 static const bool is_exact
= true;
525 static const int radix
= 2;
526 static unsigned int epsilon() throw()
528 static unsigned int round_error() throw()
531 static const int min_exponent
= 0;
532 static const int min_exponent10
= 0;
533 static const int max_exponent
= 0;
534 static const int max_exponent10
= 0;
536 static const bool has_infinity
= false;
537 static const bool has_quiet_NaN
= false;
538 static const bool has_signaling_NaN
= false;
539 static const float_denorm_style has_denorm
= denorm_absent
;
540 static const bool has_denorm_loss
= false;
542 static unsigned int infinity() throw()
543 { return static_cast<unsigned int>(0); }
544 static unsigned int quiet_NaN() throw()
545 { return static_cast<unsigned int>(0); }
546 static unsigned int signaling_NaN() throw()
547 { return static_cast<unsigned int>(0); }
548 static unsigned int denorm_min() throw()
549 { return static_cast<unsigned int>(0); }
551 static const bool is_iec559
= true;
552 static const bool is_bounded
= true;
553 static const bool is_modulo
= true;
555 static const bool traps
= true;
556 static const bool tinyness_before
= false;
557 static const float_round_style round_style
= round_toward_zero
;
560 template<> struct numeric_limits
<long> {
561 static const bool is_specialized
= true;
563 static long min() throw()
565 static long max() throw()
568 static const int digits
= 31;
569 static const int digits10
= 9;
570 static const bool is_signed
= true;
571 static const bool is_integer
= true;
572 static const bool is_exact
= true;
573 static const int radix
= 2;
574 static long epsilon() throw()
576 static long round_error() throw()
579 static const int min_exponent
= 0;
580 static const int min_exponent10
= 0;
581 static const int max_exponent
= 0;
582 static const int max_exponent10
= 0;
584 static const bool has_infinity
= false;
585 static const bool has_quiet_NaN
= false;
586 static const bool has_signaling_NaN
= false;
587 static const float_denorm_style has_denorm
= denorm_absent
;
588 static const bool has_denorm_loss
= false;
590 static long infinity() throw()
591 { return static_cast<long>(0); }
592 static long quiet_NaN() throw()
593 { return static_cast<long>(0); }
594 static long signaling_NaN() throw()
595 { return static_cast<long>(0); }
596 static long denorm_min() throw()
597 { return static_cast<long>(0); }
599 static const bool is_iec559
= true;
600 static const bool is_bounded
= true;
601 static const bool is_modulo
= false;
603 static const bool traps
= false;
604 static const bool tinyness_before
= false;
605 static const float_round_style round_style
= round_toward_zero
;
608 template<> struct numeric_limits
<unsigned long> {
609 static const bool is_specialized
= true;
611 static unsigned long min() throw()
613 static unsigned long max() throw()
614 { return ULONG_MAX
; }
616 static const int digits
= 32;
617 static const int digits10
= 9;
618 static const bool is_signed
= false;
619 static const bool is_integer
= true;
620 static const bool is_exact
= true;
621 static const int radix
= 2;
622 static unsigned long epsilon() throw()
624 static unsigned long round_error() throw()
627 static const int min_exponent
= 0;
628 static const int min_exponent10
= 0;
629 static const int max_exponent
= 0;
630 static const int max_exponent10
= 0;
632 static const bool has_infinity
= false;
633 static const bool has_quiet_NaN
= false;
634 static const bool has_signaling_NaN
= false;
635 static const float_denorm_style has_denorm
= denorm_absent
;
636 static const bool has_denorm_loss
= false;
638 static unsigned long infinity() throw()
639 { return static_cast<unsigned long>(0); }
640 static unsigned long quiet_NaN() throw()
641 { return static_cast<unsigned long>(0); }
642 static unsigned long signaling_NaN() throw()
643 { return static_cast<unsigned long>(0); }
644 static unsigned long denorm_min() throw()
645 { return static_cast<unsigned long>(0); }
647 static const bool is_iec559
= true;
648 static const bool is_bounded
= true;
649 static const bool is_modulo
= true;
651 static const bool traps
= true;
652 static const bool tinyness_before
= false;
653 static const float_round_style round_style
= round_toward_zero
;
656 template<> struct numeric_limits
<float> {
657 static const bool is_specialized
= true;
659 static float min() throw()
661 static float max() throw()
664 static const int digits
= FLT_MANT_DIG
;
665 static const int digits10
= FLT_DIG
;
666 static const bool is_signed
= true;
667 static const bool is_integer
= false;
668 static const bool is_exact
= false;
669 static const int radix
= FLT_RADIX
;
670 static float epsilon() throw()
671 { return FLT_EPSILON
; }
672 static float round_error() throw()
673 { return FLT_ROUNDS
; }
675 static const int min_exponent
= FLT_MIN_EXP
;
676 static const int min_exponent10
= FLT_MIN_10_EXP
;
677 static const int max_exponent
= FLT_MAX_EXP
;
678 static const int max_exponent10
= FLT_MAX_10_EXP
;
680 static const bool has_infinity
= false;
681 static const bool has_quiet_NaN
= false;
682 static const bool has_signaling_NaN
= false;
683 static const float_denorm_style has_denorm
= denorm_absent
;
684 static const bool has_denorm_loss
= false;
686 static float infinity() throw()
687 { return static_cast<float>(0); }
688 static float quiet_NaN() throw()
689 { return static_cast<float>(0); }
690 static float signaling_NaN() throw()
691 { return static_cast<float>(0); }
692 static float denorm_min() throw()
693 { return static_cast<float>(0); }
695 static const bool is_iec559
= false;
696 static const bool is_bounded
= true;
697 static const bool is_modulo
= false;
699 static const bool traps
= false;
700 static const bool tinyness_before
= false;
701 static const float_round_style round_style
= round_toward_zero
;
704 template<> struct numeric_limits
<double> {
705 static const bool is_specialized
= true;
707 static double min() throw()
709 static double max() throw()
712 static const int digits
= DBL_MANT_DIG
;
713 static const int digits10
= DBL_DIG
;
714 static const bool is_signed
= true;
715 static const bool is_integer
= false;
716 static const bool is_exact
= false;
717 static const int radix
= 2;
718 static double epsilon() throw()
719 { return DBL_EPSILON
; }
720 static double round_error() throw()
723 static const int min_exponent
= DBL_MIN_EXP
;
724 static const int min_exponent10
= DBL_MIN_10_EXP
;
725 static const int max_exponent
= DBL_MAX_EXP
;
726 static const int max_exponent10
= DBL_MAX_10_EXP
;
728 static const bool has_infinity
= false;
729 static const bool has_quiet_NaN
= false;
730 static const bool has_signaling_NaN
= false;
731 static const float_denorm_style has_denorm
= denorm_absent
;
732 static const bool has_denorm_loss
= false;
734 static double infinity() throw()
735 { return static_cast<double>(0); }
736 static double quiet_NaN() throw()
737 { return static_cast<double>(0); }
738 static double signaling_NaN() throw()
739 { return static_cast<double>(0); }
740 static double denorm_min() throw()
741 { return static_cast<double>(0); }
743 static const bool is_iec559
= false;
744 static const bool is_bounded
= true;
745 static const bool is_modulo
= false;
747 static const bool traps
= false;
748 static const bool tinyness_before
= false;
749 static const float_round_style round_style
= round_toward_zero
;
752 template<> struct numeric_limits
<long double> {
753 static const bool is_specialized
= true;
755 static double min() throw()
757 static double max() throw()
760 static const int digits
= LDBL_MANT_DIG
;
761 static const int digits10
= LDBL_DIG
;
762 static const bool is_signed
= true;
763 static const bool is_integer
= false;
764 static const bool is_exact
= false;
765 static const int radix
= 2;
766 static double epsilon() throw()
767 { return LDBL_EPSILON
; }
768 static double round_error() throw()
771 static const int min_exponent
= LDBL_MIN_EXP
;
772 static const int min_exponent10
= LDBL_MIN_10_EXP
;
773 static const int max_exponent
= LDBL_MAX_EXP
;
774 static const int max_exponent10
= LDBL_MAX_10_EXP
;
776 static const bool has_infinity
= false;
777 static const bool has_quiet_NaN
= false;
778 static const bool has_signaling_NaN
= false;
779 static const float_denorm_style has_denorm
= denorm_absent
;
780 static const bool has_denorm_loss
= false;
782 static double infinity() throw()
783 { return static_cast<double>(0); }
784 static double quiet_NaN() throw()
785 { return static_cast<double>(0); }
786 static double signaling_NaN() throw()
787 { return static_cast<double>(0); }
788 static double denorm_min() throw()
789 { return static_cast<double>(0); }
791 static const bool is_iec559
= false;
792 static const bool is_bounded
= true;
793 static const bool is_modulo
= false;
795 static const bool traps
= false;
796 static const bool tinyness_before
= false;
797 static const float_round_style round_style
= round_toward_zero
;
802 #endif // _CPP_NUMERIC_LIMITS