34#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
37# define _RWSTD_NO_IMPLICIT_INCLUSION
50#ifndef _RWSTD_NO_IEEEFP_H
59# define FLT_ROUNDS _RWSTD_FLT_ROUNDS
65static const int endian_test = 1;
68extern const bool big_endian = !*(
const char*)&endian_test;
75#ifndef _RWSTD_NO_LONG_DOUBLE
85const char* fpclass_name (
int fpc)
88 case _FPCLASS_SNAN:
return "_FPCLASS_SNAN";
89 case _FPCLASS_QNAN:
return "_FPCLASS_QNAN";
90 case _FPCLASS_NINF:
return "_FPCLASS_NINF";
91 case _FPCLASS_NN:
return "_FPCLASS_NN";
92 case _FPCLASS_ND:
return "_FPCLASS_ND";
93 case _FPCLASS_NZ:
return "_FPCLASS_NZ";
94 case _FPCLASS_PZ:
return "_FPCLASS_PZ";
95 case _FPCLASS_PD:
return "_FPCLASS_PD";
96 case _FPCLASS_PN:
return "_FPCLASS_PN";
97 case _FPCLASS_PINF:
return "_FPCLASS_PINF";
100 static char buf [16];
101 std::sprintf (
buf,
"%#x", fpc);
105#elif defined (_RWSTD_OS_SUNOS)
107const char* fpclass_name (fpclass_t fpc)
110 case FP_SNAN:
return "FP_SNAN";
111 case FP_QNAN:
return "FP_QNAN";
112 case FP_NINF:
return "FP_NINF";
113 case FP_PINF:
return "FP_PINF";
114 case FP_NDENORM:
return "FP_NDENORM";
115 case FP_PDENORM:
return "FP_PDENORM";
116 case FP_NZERO:
return "FP_NZERO";
117 case FP_PZERO:
return "FP_PZERO";
118 case FP_NNORM:
return "FP_NNORM";
119 case FP_PNORM:
return "FP_PNORM";
123 static char buf [16];
124 std::sprintf (
buf,
"%#x", fpc);
128#elif defined (fpclassify)
130const char* fpclass_name (
int fpc)
134 case FP_INFINITE:
return "FP_INFINITE";
137 case FP_NAN:
return "FP_NAN";
140 case FP_NORMAL:
return "FP_NORMAL";
143 case FP_SUBNORMAL:
return "FP_SUBNORMAL";
146 case FP_ZERO:
return "FP_ZERO";
151 static char buf [16];
152 std::sprintf (
buf,
"%#x", fpc);
162inline int _fpclass (
float val)
166 if (0 == (lval & 0x7FFFFFFF))
167 return lval ? _FPCLASS_NZ : _FPCLASS_PZ;
169 if (0 == (lval & 0x7F800000))
170 return (lval & 0x80000000) ? _FPCLASS_ND : _FPCLASS_PD;
172 if (0x7F800000 == (lval & 0x7FFFFFFF))
173 return (lval & 0x80000000) ? _FPCLASS_NINF : _FPCLASS_PINF;
175 if (0x7F800000 == (lval & 0x7F800000))
176 return (lval & 0x00400000) ? _FPCLASS_QNAN : _FPCLASS_SNAN;
178 return (lval & 0x80000000) ? _FPCLASS_NN : _FPCLASS_PN;
181inline int _fpclass (
long double val)
183 return _fpclass (
double (
val));
188template <
class FloatT>
191 if (!std::numeric_limits<FloatT>::traps) {
195 "numeric_limits<%s>::infinity() > "
196 "numeric_limits<%s>::max()", tname, tname);
199 rw_assert (inf == inf * inf, 0, __LINE__,
200 "numeric_limits<%s>::infinity()", tname);
205 const int fpc = _fpclass (inf);
206 rw_assert (_FPCLASS_PINF == fpc, 0, __LINE__,
207 "_fpclass (numeric_limits<%s>::infinity()) == "
208 "%d (_FPCLASS_PINF), got %d (%s)",
209 tname, _FPCLASS_PINF, fpc, fpclass_name (fpc));
211#elif defined (_RWSTD_OS_SUNOS)
214 "finite (numeric_limits<%s>::infinity()) == 0, "
215 "got non-zero", tname);
217 const fpclass_t fpc = fpclass (inf);
218 rw_assert (FP_PINF == fpclass (inf), 0, __LINE__,
219 "fpclass (numeric_limits<%s>::infinity()) == %d (FP_PINF), "
220 "got %d (%s)", tname, FP_PINF, fpc, fpclass_name (fpc));
227 "isinf (numeric_limits<%s>::infinity()) != 0, got 0",
234 const int fpc = fpclassify (inf);
235 rw_assert (FP_INFINITE == fpc, 0, __LINE__,
236 "fpclassify(numeric_limits<%s>::infinity()) == "
237 "%d (FP_INFINITE), got %d (%s)", tname,
238 FP_INFINITE, fpc, fpclass_name (fpc));
248template <
class FloatT>
252 rw_assert (!(qnan == qnan2), 0, __LINE__,
253 "numeric_limits<%s>::quiet_NaN() != "
254 "numeric_limits<%1$s>::quiet_NaN()",
257 const FloatT inf = std::numeric_limits<FloatT>::infinity ();
260 "numeric_limits<%s>::quiet_NaN() != "
261 "numeric_limits<%1$s>::infinity()",
265 "numeric_limits<%s>::quiet_NaN() != "
266 "-numeric_limits<%1$s>::infinity()",
271 rw_assert (0 != _isnan (qnan), 0, __LINE__,
272 "_isnan(numeric_limits<%s>::quiet_NaN()) != 0, got 0",
275 const int fpc = _fpclass (qnan);
276 rw_assert (_FPCLASS_QNAN == fpc, 0, __LINE__,
277 "_fpclass(numeric_limits<%s>::quiet_NaN()) == "
278 "%d (_FPCLASS_QNAN), got %d (%s)",
279 tname, _FPCLASS_QNAN, fpc, fpclass_name (fpc));
281#elif defined (_RWSTD_OS_SUNOS)
284 "finite(numeric_limits<%s>::quiet_NaN()) == 0, "
285 "got non-zero", tname);
287 const fpclass_t fpc = fpclass (qnan);
289 "fpclass(numeric_limits<%s>::infinity()) == %d (FP_QNAN), "
290 "got %d (%s)", tname, FP_QNAN, fpc, fpclass_name (fpc));
296 rw_assert (0 != isnan (qnan), 0, __LINE__,
297 "isnan(numeric_limits<%s>::quiet_NaN()) != 0, got 0",
304 const int fpc = fpclassify (qnan);
306 "fpclassify(numeric_limits<%s>::quiet_NaN()) == "
307 "%d (FP_NAN), got %d (%s)", tname,
308 FP_NAN, fpc, fpclass_name (fpc));
318template <
class FloatT>
322 rw_assert (!(snan == snan2), 0, __LINE__,
323 "numeric_limits<%s>::signaling_NaN() != "
324 "numeric_limits<%1$s>::signaling_NaN()",
327 const FloatT inf = std::numeric_limits<FloatT>::infinity ();
330 "numeric_limits<%s>::signaling_NaN() != "
331 "numeric_limits<%1$s>::infinity()",
335 "numeric_limits<%s>::signaling_NaN() != "
336 "-numeric_limits<%1$s>::infinity()",
341 rw_assert (0 != _isnan (snan), 0, __LINE__,
342 "_isnan (numeric_limits<%s>::signaling_NaN()) != 0, got 0",
345 const int fpc = _fpclass (snan);
346 rw_assert (_FPCLASS_SNAN == fpc, 0, __LINE__,
347 "_fpclass(numeric_limits<%s>::signaling_NaN()) == "
348 "%d (_FPCLASS_SNAN), got %d (%s)",
349 tname, _FPCLASS_SNAN, fpc, fpclass_name (fpc));
351#elif defined (_RWSTD_OS_SUNOS)
354 "finite(numeric_limits<%s>::signaling_NaN()) == 0, "
355 "got non-zero", tname);
357 const fpclass_t fpc = fpclass (snan);
359 "fpclass(numeric_limits<%s>::signaling_NaN()) == %d "
360 "(FP_SNAN), got %d (%s)", tname,
361 FP_SNAN, fpc, fpclass_name (fpc));
366 rw_assert (0 != isnan (snan), 0, __LINE__,
367 "isnan(numeric_limits<%s>::signaling_NaN()) != 0, got 0",
374 const int fpc = fpclassify (snan);
376 "fpclassify(numeric_limits<%s>::signaling_NaN()) == "
377 "%d (FP_NAN), got %d (%s)", tname,
378 FP_NAN, fpc, fpclass_name (fpc));
391#if defined (__alpha) && !defined (__linux__) \
392 && !defined (__VMS) && defined (__DECCXX) && defined (__PURE_CNAME)
394extern "C" unsigned int read_rnd ();
395#define read_rnd read_rnd
423 if (rounding == std::round_indeterminate)
428 case std::round_toward_zero:
429 case std::round_toward_infinity:
430 case std::round_toward_neg_infinity:
467#if defined (FLT_SNAN)
470# ifndef _RWSTD_NO_SIGNALING_NAN
483 || defined (__hpux) \
484 || defined (__osf__) \
485 || defined (_MSC_VER)
486 return std::denorm_present;
488 return std::denorm_indeterminate;
498#if defined (FLT_INFINITY)
500#elif defined (_RWSTD_NO_DBL_TRAPS)
502 float inf = float (std::atof (
"inf"));
512 char bits [
sizeof (float)];
528#elif defined (FLT_QNAN)
530#elif defined (_RWSTD_NO_DBL_TRAPS)
532 float nan = float (std::atof (
"nan"));
534 if (nan !=
float (std::atof (
"nan")))
543 char bits [
sizeof (float)];
558#if defined (FLT_SNAN)
560#elif defined (_RWSTD_NO_DBL_TRAPS)
564 char bits [
sizeof (float)];
567 snan.val = infinity ();
572 snan.bits [
sizeof snan.val - 2] =
'\xc0';
575 snan.bits [1] =
'\xc0';
583 snan.bits [
sizeof snan.val - 1] |= 1;
596 char bits [
sizeof (float)];
611#if defined (__FLT_DENORM_MIN__)
613 return __FLT_DENORM_MIN__;
614#elif defined (__osf__)
615 const unsigned short pos_denorm [] = { 0x0001, 0x0000 };
622 char denorm_min_bits [
sizeof (float)];
626 u.denorm_min_bits [
sizeof (float) - 1] =
'\001';
628 u.denorm_min_bits [0] =
'\001';
659 static bool traps () {
return true; }
666 return std::round_to_nearest;
700 if (rounding == std::round_indeterminate)
704 case std::round_toward_zero:
705 case std::round_toward_infinity:
706 case std::round_toward_neg_infinity:
739# ifndef _RWSTD_NO_SIGNALING_NAN
751 || defined (__hpux) \
752 || defined (__osf__) \
753 || defined (_MSC_VER)
754 return std::denorm_present;
756 return std::denorm_indeterminate;
766#if defined (DBL_INFINITY)
768#elif defined (_RWSTD_NO_DBL_TRAPS)
770 double inf = std::atof (
"inf");
780 char bits [
sizeof (double)];
796#elif defined (DBL_QNAN)
798#elif defined (_RWSTD_NO_DBL_TRAPS)
800 double nan = std::atof (
"nan");
802 if (nan != std::atof (
"nan"))
811 char bits [
sizeof (double)];
826#if defined (DBL_SNAN)
828#elif defined (_RWSTD_NO_DBL_TRAPS)
832 char bits [
sizeof (double)];
835 snan.val = infinity ();
840 snan.bits [
sizeof snan.val - 2] =
'\xf8';
843 snan.bits [1] =
'\xf8';
851 snan.bits [
sizeof snan.val - 1] |= 1;
864 char bits [
sizeof (double)];
879#if defined (__DBL_DENORM_MIN__)
881 return __DBL_DENORM_MIN__;
882#elif defined (__osf__)
883 const unsigned short pos_denorm [] = { 0x0001, 0x0000 };
890 char denorm_min_bits [
sizeof (double)];
894 u.denorm_min_bits [
sizeof (double) - 1] =
'\001';
896 u.denorm_min_bits [0] =
'\001';
923 static bool traps () {
return true; }
930 return std::round_to_nearest;
964 if (rounding == std::round_indeterminate)
968 case std::round_toward_zero:
969 case std::round_toward_infinity:
970 case std::round_toward_neg_infinity:
997#if defined (LDBL_SNAN)
1000# ifndef _RWSTD_NO_SIGNALING_NAN
1012 || defined (__hpux) \
1013 || defined (__osf__) \
1014 || defined (_MSC_VER)
1015 return std::denorm_present;
1017 return std::denorm_indeterminate;
1026#if defined (LDBL_INFINITY)
1027 return LDBL_INFINITY;
1028#elif defined (_RWSTD_NO_DBL_TRAPS)
1030 long double inf = std::atof (
"inf");
1040 char bits [
sizeof (
long double)];
1043 _RWSTD_LDBL_INF_BITS
1056#elif defined (LDBL_QNAN)
1058#elif defined (_RWSTD_NO_DBL_TRAPS)
1060 long double nan = std::atof (
"nan");
1062 if (nan != (
long double)std::atof (
"nan"))
1071 char bits [
sizeof (
long double)];
1074 _RWSTD_LDBL_QNAN_BITS
1086#if defined (LDBL_SNAN)
1088#elif defined (_RWSTD_NO_DBL_TRAPS)
1092 char bits [
sizeof (
long double)];
1095 snan.val = infinity ();
1100 snan.bits [
sizeof snan.val - 3] =
'\x80';
1103 snan.bits [2] =
'\x80';
1111 snan.bits [
sizeof snan.val - 1] |= 1;
1124 char bits [
sizeof (
long double)];
1127 _RWSTD_LDBL_SNAN_BITS
1139#if defined (__LDBL_DENORM_MIN__)
1141 return __LDBL_DENORM_MIN__;
1142#elif defined (__osf__)
1143 const unsigned short pos_denorm [] = { 0x0001, 0x0000 };
1149 long double denorm_min;
1150 char denorm_min_bits [
sizeof (
long double)];
1154 u.denorm_min_bits [
sizeof (
long double) - 1] =
'\001';
1156 u.denorm_min_bits [0] =
'\001';
1158 return u.denorm_min;
1165#if defined (__osf__)
1184 return std::round_to_nearest;
1193template <
class FloatT>
1196 typedef std::numeric_limits<FloatT> FLim;
1200#if defined (__alpha)
1204#elif defined (__hpux) && defined (_BIG_ENDIAN)
1206#elif defined (__i386__)
1208#elif defined (__sparc)
1210#elif defined (_WIN64)
1212#elif defined (_WIN32)
1216#ifndef _RWSTD_NO_STATIC_CONST_MEMBER_INIT
1218# if !defined (__EDG__) || __EDG_VERSION__ > 245
1219# define CHECK_CONST(const_int) \
1220 enum { e = const_int }; \
1224# define CHECK_CONST(const_int) \
1225 switch (const_int) { case const_int: break; }; \
1231# define CHECK_CONST(const_int) enum { e = const_int }
1236#define VERIFY_DATA(member) do { \
1238 CHECK_CONST (FLim::member); \
1240 rw_assert (FLim::member == FVal::member (), 0, __LINE__, \
1241 "numeric_limits<%s>::" #member " == %i, got %i", \
1242 tname, FVal::member (), FLim::member); \
1246#define VERIFY_CONST(member, value) do { \
1248 CHECK_CONST (FLim::member); \
1250 rw_assert (FLim::member == value, 0, __LINE__, \
1251 "numeric_limits<%s>::" #member " == %i, got %i", \
1252 tname, FVal::member (), value); \
1256#define VERIFY_FUNCTION(member) do { \
1258 FloatT (*pf)() _PTR_THROWS(()) = &FLim::member; \
1259 _RWSTD_UNUSED (pf); \
1261 rw_assert ( FLim::member () == FVal::member () \
1262 || ( FLim::member () != FLim::member () \
1263 && FVal::member () != FVal::member ()), \
1265 "numeric_limits<%s>::" #member "() == %{@}, got %{@}", \
1266 tname, fmt, FVal::member (), fmt, FLim::member ()); \
1269#define VERIFY_SIGNATURE(member) do { \
1271 FloatT (*pf)() _PTR_THROWS(()) = &FLim::member; \
1272 _RWSTD_UNUSED (pf); \
1297 if (FLim::has_infinity)
1300 if (std::numeric_limits<FloatT>::traps)
1305 if (FLim::has_quiet_NaN)
1307 FLim::quiet_NaN (), tname);
1310 if (std::numeric_limits<FloatT>::traps)
1315 if (FLim::has_signaling_NaN)
1317 FLim::signaling_NaN (), tname);
1320 if (std::numeric_limits<FloatT>::traps) {
1331 if (
sizeof (FloatT) >
sizeof (
float)) {
1335 const FloatT denorm_min = FLim::denorm_min ();
1337 const int fpc = _fpclass (
double (denorm_min));
1339 rw_assert (_FPCLASS_PD == fpc, 0, __LINE__,
1340 "_fpclass(numeric_limits<%s>::denorm_min()) == "
1341 "%d (_FPCLASS_PD), got %d (%s)",
1342 tname, _FPCLASS_PD, fpc, fpclass_name (fpc));
1366 volatile FloatT
zero = 0;
1369 const FloatT inf = FLim::infinity ();
1371 FloatT nan =
zero * inf;
1380 if (FLim::is_iec559) {
1409#define VERIFY_CONST(x, value) do { \
1411 rw_assert (value == x, 0, __LINE__, \
1412 #x " == %d, got %d", value, x); \
1423 VERIFY_CONST (std::denorm_indeterminate, std::float_denorm_style (-1));
1424 VERIFY_CONST (std::denorm_absent, std::float_denorm_style (0));
1425 VERIFY_CONST (std::denorm_present, std::float_denorm_style (1));
1430#ifndef _RWSTD_NO_LONG_DOUBLE
1433# if !defined (__SUNPRO_CC) || __SUNPRO_CC > 0x530
1436 test_limits ((
long double)0.0,
"long double", fmt);
1452 return rw_test (argc, argv, __FILE__,
1454 "floating specializations",
#define VERIFY_SIGNATURE(member)
#define VERIFY_CONST(member, value)
void test_infinity(FloatT inf, FloatT max, const char *tname)
void test_signaling_NaN(FloatT snan, FloatT snan2, const char *tname)
volatile long double ldbl_zero
void test_quiet_NaN(FloatT qnan, FloatT qnan2, const char *tname)
void test_limits(FloatT, const char *tname, const char *fmt)
#define VERIFY_DATA(member)
#define VERIFY_FUNCTION(member)
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define _RWSTD_SPECIALIZED_CLASS
#define _RWSTD_LDBL_PRINTF_PREFIX
#define _RWSTD_REINTERPRET_CAST(T, x)
#define _RWSTD_UNUSED(arg)
#define _RWSTD_STATIC_CAST(T, x)
constexpr bool is_integer
Metafunction for determining if a type is, or is a reference to, a int64_t or toml::value<int64_t>.
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
_TEST_EXPORT int rw_warn(int, const char *, int, const char *,...)
static std::float_round_style round_style()
static double denorm_min()
static int max_exponent()
static bool is_specialized()
static bool has_denorm_loss()
static std::float_denorm_style has_denorm()
static double signaling_NaN()
static bool tinyness_before()
static int min_exponent()
static int min_exponent10()
static double round_error()
static bool has_signaling_NaN()
static bool has_infinity()
static bool has_quiet_NaN()
static double quiet_NaN()
static int max_exponent10()
static float signaling_NaN()
static std::float_round_style round_style()
static float round_error()
static bool has_denorm_loss()
static bool tinyness_before()
static int max_exponent10()
static float denorm_min()
static int max_exponent()
static int min_exponent10()
static bool is_specialized()
static bool has_infinity()
static bool has_quiet_NaN()
static int min_exponent()
static std::float_denorm_style has_denorm()
static bool has_signaling_NaN()
static int min_exponent()
static bool has_infinity()
static long double denorm_min()
static long double quiet_NaN()
static bool has_signaling_NaN()
static bool tinyness_before()
static long double infinity()
static long double round_error()
static int min_exponent10()
static long double signaling_NaN()
static bool has_denorm_loss()
static std::float_denorm_style has_denorm()
static bool is_specialized()
static long double epsilon()
static int max_exponent10()
static int max_exponent()
static std::float_round_style round_style()
static bool has_quiet_NaN()