Skip to content

Commit bda33f9

Browse files
committed
Add unit tests for serfloat module
1 parent 2be4cd9 commit bda33f9

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

src/Makefile.test.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ BITCOIN_TESTS =\
121121
test/script_tests.cpp \
122122
test/script_standard_tests.cpp \
123123
test/scriptnum_tests.cpp \
124+
test/serfloat_tests.cpp \
124125
test/serialize_tests.cpp \
125126
test/settings_tests.cpp \
126127
test/sighash_tests.cpp \

src/test/serfloat_tests.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (c) 2014-2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <test/util/setup_common.h>
6+
#include <util/serfloat.h>
7+
8+
#include <boost/test/unit_test.hpp>
9+
10+
#include <cmath>
11+
#include <limits>
12+
13+
BOOST_FIXTURE_TEST_SUITE(serfloat_tests, BasicTestingSetup)
14+
15+
namespace {
16+
17+
uint64_t TestDouble(double f) {
18+
uint64_t i = EncodeDouble(f);
19+
double f2 = DecodeDouble(i);
20+
if (std::isnan(f)) {
21+
// NaN is not guaranteed to round-trip exactly.
22+
BOOST_CHECK(std::isnan(f2));
23+
} else {
24+
// Everything else is.
25+
BOOST_CHECK(!std::isnan(f2));
26+
uint64_t i2 = EncodeDouble(f2);
27+
BOOST_CHECK_EQUAL(f, f2);
28+
BOOST_CHECK_EQUAL(i, i2);
29+
}
30+
return i;
31+
}
32+
33+
} // namespace
34+
35+
BOOST_AUTO_TEST_CASE(double_serfloat_tests) {
36+
BOOST_CHECK_EQUAL(TestDouble(0.0), 0);
37+
BOOST_CHECK_EQUAL(TestDouble(-0.0), 0x8000000000000000);
38+
BOOST_CHECK_EQUAL(TestDouble(std::numeric_limits<double>::infinity()), 0x7ff0000000000000);
39+
BOOST_CHECK_EQUAL(TestDouble(-std::numeric_limits<double>::infinity()), 0xfff0000000000000);
40+
41+
if (std::numeric_limits<float>::is_iec559) {
42+
BOOST_CHECK_EQUAL(sizeof(double), 8);
43+
BOOST_CHECK_EQUAL(sizeof(uint64_t), 8);
44+
// Test extreme values
45+
TestDouble(std::numeric_limits<double>::min());
46+
TestDouble(-std::numeric_limits<double>::min());
47+
TestDouble(std::numeric_limits<double>::max());
48+
TestDouble(-std::numeric_limits<double>::max());
49+
TestDouble(std::numeric_limits<double>::lowest());
50+
TestDouble(-std::numeric_limits<double>::lowest());
51+
TestDouble(std::numeric_limits<double>::quiet_NaN());
52+
TestDouble(-std::numeric_limits<double>::quiet_NaN());
53+
TestDouble(std::numeric_limits<double>::signaling_NaN());
54+
TestDouble(-std::numeric_limits<double>::signaling_NaN());
55+
TestDouble(std::numeric_limits<double>::denorm_min());
56+
TestDouble(-std::numeric_limits<double>::denorm_min());
57+
// Test exact encoding: on currently supported platforms, EncodeDouble
58+
// should produce exactly the same as the in-memory representation for non-NaN.
59+
for (int j = 0; j < 1000; ++j) {
60+
// Iterate over 9 specific bits exhaustively; the others are chosen randomly.
61+
// These specific bits are the sign bit, and the 2 top and bottom bits of
62+
// exponent and mantissa in the IEEE754 binary64 format.
63+
for (int x = 0; x < 512; ++x) {
64+
uint64_t v = InsecureRandBits(64);
65+
v &= ~(uint64_t{1} << 0);
66+
if (x & 1) v |= (uint64_t{1} << 0);
67+
v &= ~(uint64_t{1} << 1);
68+
if (x & 2) v |= (uint64_t{1} << 1);
69+
v &= ~(uint64_t{1} << 50);
70+
if (x & 4) v |= (uint64_t{1} << 50);
71+
v &= ~(uint64_t{1} << 51);
72+
if (x & 8) v |= (uint64_t{1} << 51);
73+
v &= ~(uint64_t{1} << 52);
74+
if (x & 16) v |= (uint64_t{1} << 52);
75+
v &= ~(uint64_t{1} << 53);
76+
if (x & 32) v |= (uint64_t{1} << 53);
77+
v &= ~(uint64_t{1} << 61);
78+
if (x & 64) v |= (uint64_t{1} << 61);
79+
v &= ~(uint64_t{1} << 62);
80+
if (x & 128) v |= (uint64_t{1} << 62);
81+
v &= ~(uint64_t{1} << 63);
82+
if (x & 256) v |= (uint64_t{1} << 63);
83+
double f;
84+
memcpy(&f, &v, 8);
85+
uint64_t v2 = TestDouble(f);
86+
if (!std::isnan(f)) BOOST_CHECK_EQUAL(v, v2);
87+
}
88+
}
89+
}
90+
}
91+
92+
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)