@@ -37,6 +37,7 @@ uint64_t TestDouble(double f) {
3737} // namespace
3838
3939BOOST_AUTO_TEST_CASE (double_serfloat_tests) {
40+ // Test specific values against their expected encoding.
4041 BOOST_CHECK_EQUAL (TestDouble (0.0 ), 0U );
4142 BOOST_CHECK_EQUAL (TestDouble (-0.0 ), 0x8000000000000000 );
4243 BOOST_CHECK_EQUAL (TestDouble (std::numeric_limits<double >::infinity ()), 0x7ff0000000000000U );
@@ -46,55 +47,76 @@ BOOST_AUTO_TEST_CASE(double_serfloat_tests) {
4647 BOOST_CHECK_EQUAL (TestDouble (2.0 ), 0x4000000000000000ULL );
4748 BOOST_CHECK_EQUAL (TestDouble (4.0 ), 0x4010000000000000ULL );
4849 BOOST_CHECK_EQUAL (TestDouble (785.066650390625 ), 0x4088888880000000ULL );
50+ BOOST_CHECK_EQUAL (TestDouble (3.7243058682384174 ), 0x400dcb60e0031440 );
51+ BOOST_CHECK_EQUAL (TestDouble (91.64070592566159 ), 0x4056e901536d447a );
52+ BOOST_CHECK_EQUAL (TestDouble (-98.63087668642575 ), 0xc058a860489c007a );
53+ BOOST_CHECK_EQUAL (TestDouble (4.908737756962054 ), 0x4013a28c268b2b70 );
54+ BOOST_CHECK_EQUAL (TestDouble (77.9247330021754 ), 0x40537b2ed3547804 );
55+ BOOST_CHECK_EQUAL (TestDouble (40.24732825357566 ), 0x40441fa873c43dfc );
56+ BOOST_CHECK_EQUAL (TestDouble (71.39395607929222 ), 0x4051d936938f27b6 );
57+ BOOST_CHECK_EQUAL (TestDouble (58.80100710817612 ), 0x404d668766a2bd70 );
58+ BOOST_CHECK_EQUAL (TestDouble (-30.10665786964975 ), 0xc03e1b4dee1e01b8 );
59+ BOOST_CHECK_EQUAL (TestDouble (60.15231509068704 ), 0x404e137f0f969814 );
60+ BOOST_CHECK_EQUAL (TestDouble (-48.15848711335961 ), 0xc04814494e445bc6 );
61+ BOOST_CHECK_EQUAL (TestDouble (26.68450101125353 ), 0x403aaf3b755169b0 );
62+ BOOST_CHECK_EQUAL (TestDouble (-65.72071986604303 ), 0xc0506e2046378ede );
63+ BOOST_CHECK_EQUAL (TestDouble (17.95575825512381 ), 0x4031f4ac92b0a388 );
64+ BOOST_CHECK_EQUAL (TestDouble (-35.27171863226279 ), 0xc041a2c7ad17a42a );
65+ BOOST_CHECK_EQUAL (TestDouble (-8.58810329425124 ), 0xc0212d1bdffef538 );
66+ BOOST_CHECK_EQUAL (TestDouble (88.51393044338977 ), 0x405620e43c83b1c8 );
67+ BOOST_CHECK_EQUAL (TestDouble (48.07224932612732 ), 0x4048093f77466ffc );
68+ BOOST_CHECK_EQUAL (TestDouble (9.867348871395659e+117 ), 0x586f4daeb2459b9f );
69+ BOOST_CHECK_EQUAL (TestDouble (-1.5166424385129721e+206 ), 0xeabe3bbc484bd458 );
70+ BOOST_CHECK_EQUAL (TestDouble (-8.585156555624594e-275 ), 0x8707c76eee012429 );
71+ BOOST_CHECK_EQUAL (TestDouble (2.2794371091628822e+113 ), 0x5777b2184458f4ee );
72+ BOOST_CHECK_EQUAL (TestDouble (-1.1290476594131867e+163 ), 0xe1c91893d3488bb0 );
73+ BOOST_CHECK_EQUAL (TestDouble (9.143848423979275e-246 ), 0x0d0ff76e5f2620a3 );
74+ BOOST_CHECK_EQUAL (TestDouble (-2.8366718125941117e+81 ), 0xd0d7ec7e754b394a );
75+ BOOST_CHECK_EQUAL (TestDouble (-1.2754409481684012e+229 ), 0xef80d32f8ec55342 );
76+ BOOST_CHECK_EQUAL (TestDouble (6.000577060053642e-186 ), 0x197a1be7c8209b6a );
77+ BOOST_CHECK_EQUAL (TestDouble (2.0839423284378986e-302 ), 0x014c94f8689cb0a5 );
78+ BOOST_CHECK_EQUAL (TestDouble (-1.422140051483753e+259 ), 0xf5bd99271d04bb35 );
79+ BOOST_CHECK_EQUAL (TestDouble (-1.0593973991188853e+46 ), 0xc97db0cdb72d1046 );
80+ BOOST_CHECK_EQUAL (TestDouble (2.62945125875249e+190 ), 0x67779b36366c993b );
81+ BOOST_CHECK_EQUAL (TestDouble (-2.920377657275094e+115 ), 0xd7e7b7b45908e23b );
82+ BOOST_CHECK_EQUAL (TestDouble (9.790289014855851e-118 ), 0x27a3c031cc428bcc );
83+ BOOST_CHECK_EQUAL (TestDouble (-4.629317182034961e-114 ), 0xa866ccf0b753705a );
84+ BOOST_CHECK_EQUAL (TestDouble (-1.7674605603846528e+279 ), 0xf9e8ed383ffc3e25 );
85+ BOOST_CHECK_EQUAL (TestDouble (2.5308171727712605e+120 ), 0x58ef5cd55f0ec997 );
86+ BOOST_CHECK_EQUAL (TestDouble (-1.05034156412799e+54 ), 0xcb25eea1b9350fa0 );
4987
50- // Roundtrip test on IEC559-compatible systems
51- if (std::numeric_limits<double >::is_iec559) {
52- BOOST_CHECK_EQUAL (sizeof (double ), 8U );
53- BOOST_CHECK_EQUAL (sizeof (uint64_t ), 8U );
54- // Test extreme values
55- TestDouble (std::numeric_limits<double >::min ());
56- TestDouble (-std::numeric_limits<double >::min ());
57- TestDouble (std::numeric_limits<double >::max ());
58- TestDouble (-std::numeric_limits<double >::max ());
59- TestDouble (std::numeric_limits<double >::lowest ());
60- TestDouble (-std::numeric_limits<double >::lowest ());
61- TestDouble (std::numeric_limits<double >::quiet_NaN ());
62- TestDouble (-std::numeric_limits<double >::quiet_NaN ());
63- TestDouble (std::numeric_limits<double >::signaling_NaN ());
64- TestDouble (-std::numeric_limits<double >::signaling_NaN ());
65- TestDouble (std::numeric_limits<double >::denorm_min ());
66- TestDouble (-std::numeric_limits<double >::denorm_min ());
67- // Test exact encoding: on currently supported platforms, EncodeDouble
68- // should produce exactly the same as the in-memory representation for non-NaN.
69- for (int j = 0 ; j < 1000 ; ++j) {
70- // Iterate over 9 specific bits exhaustively; the others are chosen randomly.
71- // These specific bits are the sign bit, and the 2 top and bottom bits of
72- // exponent and mantissa in the IEEE754 binary64 format.
73- for (int x = 0 ; x < 512 ; ++x) {
74- uint64_t v = InsecureRandBits (64 );
75- v &= ~(uint64_t {1 } << 0 );
76- if (x & 1 ) v |= (uint64_t {1 } << 0 );
77- v &= ~(uint64_t {1 } << 1 );
78- if (x & 2 ) v |= (uint64_t {1 } << 1 );
79- v &= ~(uint64_t {1 } << 50 );
80- if (x & 4 ) v |= (uint64_t {1 } << 50 );
81- v &= ~(uint64_t {1 } << 51 );
82- if (x & 8 ) v |= (uint64_t {1 } << 51 );
83- v &= ~(uint64_t {1 } << 52 );
84- if (x & 16 ) v |= (uint64_t {1 } << 52 );
85- v &= ~(uint64_t {1 } << 53 );
86- if (x & 32 ) v |= (uint64_t {1 } << 53 );
87- v &= ~(uint64_t {1 } << 61 );
88- if (x & 64 ) v |= (uint64_t {1 } << 61 );
89- v &= ~(uint64_t {1 } << 62 );
90- if (x & 128 ) v |= (uint64_t {1 } << 62 );
91- v &= ~(uint64_t {1 } << 63 );
92- if (x & 256 ) v |= (uint64_t {1 } << 63 );
93- double f;
94- memcpy (&f, &v, 8 );
95- uint64_t v2 = TestDouble (f);
96- if (!std::isnan (f)) BOOST_CHECK_EQUAL (v, v2);
88+ // Test extreme values
89+ BOOST_CHECK_EQUAL (TestDouble (std::numeric_limits<double >::min ()), 0x10000000000000 );
90+ BOOST_CHECK_EQUAL (TestDouble (-std::numeric_limits<double >::min ()), 0x8010000000000000 );
91+ BOOST_CHECK_EQUAL (TestDouble (std::numeric_limits<double >::max ()), 0x7fefffffffffffff );
92+ BOOST_CHECK_EQUAL (TestDouble (-std::numeric_limits<double >::max ()), 0xffefffffffffffff );
93+ BOOST_CHECK_EQUAL (TestDouble (std::numeric_limits<double >::lowest ()), 0xffefffffffffffff );
94+ BOOST_CHECK_EQUAL (TestDouble (-std::numeric_limits<double >::lowest ()), 0x7fefffffffffffff );
95+ BOOST_CHECK_EQUAL (TestDouble (std::numeric_limits<double >::denorm_min ()), 0x1 );
96+ BOOST_CHECK_EQUAL (TestDouble (-std::numeric_limits<double >::denorm_min ()), 0x8000000000000001 );
97+ // Note that all NaNs are encoded the same way.
98+ BOOST_CHECK_EQUAL (TestDouble (std::numeric_limits<double >::quiet_NaN ()), 0x7ff8000000000000 );
99+ BOOST_CHECK_EQUAL (TestDouble (-std::numeric_limits<double >::quiet_NaN ()), 0x7ff8000000000000 );
100+ BOOST_CHECK_EQUAL (TestDouble (std::numeric_limits<double >::signaling_NaN ()), 0x7ff8000000000000 );
101+ BOOST_CHECK_EQUAL (TestDouble (-std::numeric_limits<double >::signaling_NaN ()), 0x7ff8000000000000 );
102+
103+ // Construct doubles to test from the encoding.
104+ static_assert (sizeof (double ) == 8 );
105+ static_assert (sizeof (uint64_t ) == 8 );
106+ for (int j = 0 ; j < 1000 ; ++j) {
107+ // Iterate over 9 specific bits exhaustively; the others are chosen randomly.
108+ // These specific bits are the sign bit, and the 2 top and bottom bits of
109+ // exponent and mantissa in the IEEE754 binary64 format.
110+ for (int x = 0 ; x < 512 ; ++x) {
111+ uint64_t v = InsecureRandBits (64 );
112+ int x_pos = 0 ;
113+ for (int v_pos : {0 , 1 , 50 , 51 , 52 , 53 , 61 , 62 , 63 }) {
114+ v &= ~(uint64_t {1 } << v_pos);
115+ if ((x >> (x_pos++)) & 1 ) v |= (uint64_t {1 } << v_pos);
97116 }
117+ double f;
118+ memcpy (&f, &v, 8 );
119+ TestDouble (f);
98120 }
99121 }
100122}
0 commit comments