]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/json/test/ryu/d2s_test.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / json / test / ryu / d2s_test.cpp
CommitLineData
20effc67
TL
1// Copyright 2018 Ulf Adams
2//
3// The contents of this file may be used under the terms of the Apache License,
4// Version 2.0.
5//
6// (See accompanying file LICENSE-Apache or copy at
7// http://www.apache.org/licenses/LICENSE-2.0)
8//
9// Alternatively, the contents of this file may be used under the terms of
10// the Boost Software License, Version 1.0.
11// (See accompanying file LICENSE-Boost or copy at
12// https://www.boost.org/LICENSE_1_0.txt)
13//
14// Unless required by applicable law or agreed to in writing, this software
15// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16// KIND, either express or implied.
17
18/*
19 This is a derivative work
20*/
21
22#include <boost/json/detail/ryu/ryu.hpp>
23#include <cmath>
24#include "gtest.hpp"
25
26BOOST_JSON_NS_BEGIN
27namespace detail {
28
29namespace ryu {
30
31static double int64Bits2Double(uint64_t bits) {
32 double f;
33 memcpy(&f, &bits, sizeof(double));
34 return f;
35}
36
37static double ieeeParts2Double(const bool sign, const uint32_t ieeeExponent, const uint64_t ieeeMantissa) {
38 BOOST_ASSERT(ieeeExponent <= 2047);
39 BOOST_ASSERT(ieeeMantissa <= ((std::uint64_t)1 << 53) - 1);
40 return int64Bits2Double(((std::uint64_t)sign << 63) | ((std::uint64_t)ieeeExponent << 52) | ieeeMantissa);
41}
42
43TEST(D2sTest, Basic) {
44 ASSERT_STREQ("0E0", d2s(0.0));
45 ASSERT_STREQ("-0E0", d2s(-0.0));
46 ASSERT_STREQ("1E0", d2s(1.0));
47 ASSERT_STREQ("-1E0", d2s(-1.0));
48 ASSERT_STREQ("NaN", d2s(NAN));
49 ASSERT_STREQ("Infinity", d2s(INFINITY));
50 ASSERT_STREQ("-Infinity", d2s(-INFINITY));
51}
52
53TEST(D2sTest, SwitchToSubnormal) {
54 ASSERT_STREQ("2.2250738585072014E-308", d2s(2.2250738585072014E-308));
55}
56
57TEST(D2sTest, MinAndMax) {
58 ASSERT_STREQ("1.7976931348623157E308", d2s(int64Bits2Double(0x7fefffffffffffff)));
59 ASSERT_STREQ("5E-324", d2s(int64Bits2Double(1)));
60}
61
62TEST(D2sTest, LotsOfTrailingZeros) {
63 ASSERT_STREQ("2.9802322387695312E-8", d2s(2.98023223876953125E-8));
64}
65
66TEST(D2sTest, Regression) {
67 ASSERT_STREQ("-2.109808898695963E16", d2s(-2.109808898695963E16));
68 ASSERT_STREQ("4.940656E-318", d2s(4.940656E-318));
69 ASSERT_STREQ("1.18575755E-316", d2s(1.18575755E-316));
70 ASSERT_STREQ("2.989102097996E-312", d2s(2.989102097996E-312));
71 ASSERT_STREQ("9.0608011534336E15", d2s(9.0608011534336E15));
72 ASSERT_STREQ("4.708356024711512E18", d2s(4.708356024711512E18));
73 ASSERT_STREQ("9.409340012568248E18", d2s(9.409340012568248E18));
74 ASSERT_STREQ("1.2345678E0", d2s(1.2345678));
75}
76
77TEST(D2sTest, LooksLikePow5) {
78 // These numbers have a mantissa that is a multiple of the largest power of 5 that fits,
79 // and an exponent that causes the computation for q to result in 22, which is a corner
80 // case for Ryu.
81 ASSERT_STREQ("5.764607523034235E39", d2s(int64Bits2Double(0x4830F0CF064DD592)));
82 ASSERT_STREQ("1.152921504606847E40", d2s(int64Bits2Double(0x4840F0CF064DD592)));
83 ASSERT_STREQ("2.305843009213694E40", d2s(int64Bits2Double(0x4850F0CF064DD592)));
84}
85
86TEST(D2sTest, OutputLength) {
87 ASSERT_STREQ("1E0", d2s(1)); // already tested in Basic
88 ASSERT_STREQ("1.2E0", d2s(1.2));
89 ASSERT_STREQ("1.23E0", d2s(1.23));
90 ASSERT_STREQ("1.234E0", d2s(1.234));
91 ASSERT_STREQ("1.2345E0", d2s(1.2345));
92 ASSERT_STREQ("1.23456E0", d2s(1.23456));
93 ASSERT_STREQ("1.234567E0", d2s(1.234567));
94 ASSERT_STREQ("1.2345678E0", d2s(1.2345678)); // already tested in Regression
95 ASSERT_STREQ("1.23456789E0", d2s(1.23456789));
96 ASSERT_STREQ("1.234567895E0", d2s(1.234567895)); // 1.234567890 would be trimmed
97 ASSERT_STREQ("1.2345678901E0", d2s(1.2345678901));
98 ASSERT_STREQ("1.23456789012E0", d2s(1.23456789012));
99 ASSERT_STREQ("1.234567890123E0", d2s(1.234567890123));
100 ASSERT_STREQ("1.2345678901234E0", d2s(1.2345678901234));
101 ASSERT_STREQ("1.23456789012345E0", d2s(1.23456789012345));
102 ASSERT_STREQ("1.234567890123456E0", d2s(1.234567890123456));
103 ASSERT_STREQ("1.2345678901234567E0", d2s(1.2345678901234567));
104
105 // Test 32-bit chunking
106 ASSERT_STREQ("4.294967294E0", d2s(4.294967294)); // 2^32 - 2
107 ASSERT_STREQ("4.294967295E0", d2s(4.294967295)); // 2^32 - 1
108 ASSERT_STREQ("4.294967296E0", d2s(4.294967296)); // 2^32
109 ASSERT_STREQ("4.294967297E0", d2s(4.294967297)); // 2^32 + 1
110 ASSERT_STREQ("4.294967298E0", d2s(4.294967298)); // 2^32 + 2
111}
112
113// Test min, max shift values in shiftright128
114TEST(D2sTest, MinMaxShift) {
115 const uint64_t maxMantissa = ((std::uint64_t)1 << 53) - 1;
116
117 // 32-bit opt-size=0: 49 <= dist <= 50
118 // 32-bit opt-size=1: 30 <= dist <= 50
119 // 64-bit opt-size=0: 50 <= dist <= 50
120 // 64-bit opt-size=1: 30 <= dist <= 50
121 ASSERT_STREQ("1.7800590868057611E-307", d2s(ieeeParts2Double(false, 4, 0)));
122 // 32-bit opt-size=0: 49 <= dist <= 49
123 // 32-bit opt-size=1: 28 <= dist <= 49
124 // 64-bit opt-size=0: 50 <= dist <= 50
125 // 64-bit opt-size=1: 28 <= dist <= 50
126 ASSERT_STREQ("2.8480945388892175E-306", d2s(ieeeParts2Double(false, 6, maxMantissa)));
127 // 32-bit opt-size=0: 52 <= dist <= 53
128 // 32-bit opt-size=1: 2 <= dist <= 53
129 // 64-bit opt-size=0: 53 <= dist <= 53
130 // 64-bit opt-size=1: 2 <= dist <= 53
131 ASSERT_STREQ("2.446494580089078E-296", d2s(ieeeParts2Double(false, 41, 0)));
132 // 32-bit opt-size=0: 52 <= dist <= 52
133 // 32-bit opt-size=1: 2 <= dist <= 52
134 // 64-bit opt-size=0: 53 <= dist <= 53
135 // 64-bit opt-size=1: 2 <= dist <= 53
136 ASSERT_STREQ("4.8929891601781557E-296", d2s(ieeeParts2Double(false, 40, maxMantissa)));
137
138 // 32-bit opt-size=0: 57 <= dist <= 58
139 // 32-bit opt-size=1: 57 <= dist <= 58
140 // 64-bit opt-size=0: 58 <= dist <= 58
141 // 64-bit opt-size=1: 58 <= dist <= 58
142 ASSERT_STREQ("1.8014398509481984E16", d2s(ieeeParts2Double(false, 1077, 0)));
143 // 32-bit opt-size=0: 57 <= dist <= 57
144 // 32-bit opt-size=1: 57 <= dist <= 57
145 // 64-bit opt-size=0: 58 <= dist <= 58
146 // 64-bit opt-size=1: 58 <= dist <= 58
147 ASSERT_STREQ("3.6028797018963964E16", d2s(ieeeParts2Double(false, 1076, maxMantissa)));
148 // 32-bit opt-size=0: 51 <= dist <= 52
149 // 32-bit opt-size=1: 51 <= dist <= 59
150 // 64-bit opt-size=0: 52 <= dist <= 52
151 // 64-bit opt-size=1: 52 <= dist <= 59
152 ASSERT_STREQ("2.900835519859558E-216", d2s(ieeeParts2Double(false, 307, 0)));
153 // 32-bit opt-size=0: 51 <= dist <= 51
154 // 32-bit opt-size=1: 51 <= dist <= 59
155 // 64-bit opt-size=0: 52 <= dist <= 52
156 // 64-bit opt-size=1: 52 <= dist <= 59
157 ASSERT_STREQ("5.801671039719115E-216", d2s(ieeeParts2Double(false, 306, maxMantissa)));
158
159 // https://github.com/ulfjack/ryu/commit/19e44d16d80236f5de25800f56d82606d1be00b9#commitcomment-30146483
160 // 32-bit opt-size=0: 49 <= dist <= 49
161 // 32-bit opt-size=1: 44 <= dist <= 49
162 // 64-bit opt-size=0: 50 <= dist <= 50
163 // 64-bit opt-size=1: 44 <= dist <= 50
164 ASSERT_STREQ("3.196104012172126E-27", d2s(ieeeParts2Double(false, 934, 0x000FA7161A4D6E0Cu)));
165}
166
167TEST(D2sTest, SmallIntegers) {
168 ASSERT_STREQ("9.007199254740991E15", d2s(9007199254740991.0)); // 2^53-1
169 ASSERT_STREQ("9.007199254740992E15", d2s(9007199254740992.0)); // 2^53
170
171 ASSERT_STREQ("1E0", d2s(1.0e+0));
172 ASSERT_STREQ("1.2E1", d2s(1.2e+1));
173 ASSERT_STREQ("1.23E2", d2s(1.23e+2));
174 ASSERT_STREQ("1.234E3", d2s(1.234e+3));
175 ASSERT_STREQ("1.2345E4", d2s(1.2345e+4));
176 ASSERT_STREQ("1.23456E5", d2s(1.23456e+5));
177 ASSERT_STREQ("1.234567E6", d2s(1.234567e+6));
178 ASSERT_STREQ("1.2345678E7", d2s(1.2345678e+7));
179 ASSERT_STREQ("1.23456789E8", d2s(1.23456789e+8));
180 ASSERT_STREQ("1.23456789E9", d2s(1.23456789e+9));
181 ASSERT_STREQ("1.234567895E9", d2s(1.234567895e+9));
182 ASSERT_STREQ("1.2345678901E10", d2s(1.2345678901e+10));
183 ASSERT_STREQ("1.23456789012E11", d2s(1.23456789012e+11));
184 ASSERT_STREQ("1.234567890123E12", d2s(1.234567890123e+12));
185 ASSERT_STREQ("1.2345678901234E13", d2s(1.2345678901234e+13));
186 ASSERT_STREQ("1.23456789012345E14", d2s(1.23456789012345e+14));
187 ASSERT_STREQ("1.234567890123456E15", d2s(1.234567890123456e+15));
188
189 // 10^i
190 ASSERT_STREQ("1E0", d2s(1.0e+0));
191 ASSERT_STREQ("1E1", d2s(1.0e+1));
192 ASSERT_STREQ("1E2", d2s(1.0e+2));
193 ASSERT_STREQ("1E3", d2s(1.0e+3));
194 ASSERT_STREQ("1E4", d2s(1.0e+4));
195 ASSERT_STREQ("1E5", d2s(1.0e+5));
196 ASSERT_STREQ("1E6", d2s(1.0e+6));
197 ASSERT_STREQ("1E7", d2s(1.0e+7));
198 ASSERT_STREQ("1E8", d2s(1.0e+8));
199 ASSERT_STREQ("1E9", d2s(1.0e+9));
200 ASSERT_STREQ("1E10", d2s(1.0e+10));
201 ASSERT_STREQ("1E11", d2s(1.0e+11));
202 ASSERT_STREQ("1E12", d2s(1.0e+12));
203 ASSERT_STREQ("1E13", d2s(1.0e+13));
204 ASSERT_STREQ("1E14", d2s(1.0e+14));
205 ASSERT_STREQ("1E15", d2s(1.0e+15));
206
207 // 10^15 + 10^i
208 ASSERT_STREQ("1.000000000000001E15", d2s(1.0e+15 + 1.0e+0));
209 ASSERT_STREQ("1.00000000000001E15", d2s(1.0e+15 + 1.0e+1));
210 ASSERT_STREQ("1.0000000000001E15", d2s(1.0e+15 + 1.0e+2));
211 ASSERT_STREQ("1.000000000001E15", d2s(1.0e+15 + 1.0e+3));
212 ASSERT_STREQ("1.00000000001E15", d2s(1.0e+15 + 1.0e+4));
213 ASSERT_STREQ("1.0000000001E15", d2s(1.0e+15 + 1.0e+5));
214 ASSERT_STREQ("1.000000001E15", d2s(1.0e+15 + 1.0e+6));
215 ASSERT_STREQ("1.00000001E15", d2s(1.0e+15 + 1.0e+7));
216 ASSERT_STREQ("1.0000001E15", d2s(1.0e+15 + 1.0e+8));
217 ASSERT_STREQ("1.000001E15", d2s(1.0e+15 + 1.0e+9));
218 ASSERT_STREQ("1.00001E15", d2s(1.0e+15 + 1.0e+10));
219 ASSERT_STREQ("1.0001E15", d2s(1.0e+15 + 1.0e+11));
220 ASSERT_STREQ("1.001E15", d2s(1.0e+15 + 1.0e+12));
221 ASSERT_STREQ("1.01E15", d2s(1.0e+15 + 1.0e+13));
222 ASSERT_STREQ("1.1E15", d2s(1.0e+15 + 1.0e+14));
223
224 // Largest power of 2 <= 10^(i+1)
225 ASSERT_STREQ("8E0", d2s(8.0));
226 ASSERT_STREQ("6.4E1", d2s(64.0));
227 ASSERT_STREQ("5.12E2", d2s(512.0));
228 ASSERT_STREQ("8.192E3", d2s(8192.0));
229 ASSERT_STREQ("6.5536E4", d2s(65536.0));
230 ASSERT_STREQ("5.24288E5", d2s(524288.0));
231 ASSERT_STREQ("8.388608E6", d2s(8388608.0));
232 ASSERT_STREQ("6.7108864E7", d2s(67108864.0));
233 ASSERT_STREQ("5.36870912E8", d2s(536870912.0));
234 ASSERT_STREQ("8.589934592E9", d2s(8589934592.0));
235 ASSERT_STREQ("6.8719476736E10", d2s(68719476736.0));
236 ASSERT_STREQ("5.49755813888E11", d2s(549755813888.0));
237 ASSERT_STREQ("8.796093022208E12", d2s(8796093022208.0));
238 ASSERT_STREQ("7.0368744177664E13", d2s(70368744177664.0));
239 ASSERT_STREQ("5.62949953421312E14", d2s(562949953421312.0));
240 ASSERT_STREQ("9.007199254740992E15", d2s(9007199254740992.0));
241
242 // 1000 * (Largest power of 2 <= 10^(i+1))
243 ASSERT_STREQ("8E3", d2s(8.0e+3));
244 ASSERT_STREQ("6.4E4", d2s(64.0e+3));
245 ASSERT_STREQ("5.12E5", d2s(512.0e+3));
246 ASSERT_STREQ("8.192E6", d2s(8192.0e+3));
247 ASSERT_STREQ("6.5536E7", d2s(65536.0e+3));
248 ASSERT_STREQ("5.24288E8", d2s(524288.0e+3));
249 ASSERT_STREQ("8.388608E9", d2s(8388608.0e+3));
250 ASSERT_STREQ("6.7108864E10", d2s(67108864.0e+3));
251 ASSERT_STREQ("5.36870912E11", d2s(536870912.0e+3));
252 ASSERT_STREQ("8.589934592E12", d2s(8589934592.0e+3));
253 ASSERT_STREQ("6.8719476736E13", d2s(68719476736.0e+3));
254 ASSERT_STREQ("5.49755813888E14", d2s(549755813888.0e+3));
255 ASSERT_STREQ("8.796093022208E15", d2s(8796093022208.0e+3));
256}
257
258} // ryu
259
260} // detail
261BOOST_JSON_NS_END