1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
4 |  |  |__   |  |  | | | |  version 3.9.1
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby  granted, free of charge, to any  person obtaining a copy
12 of this software and associated  documentation files (the "Software"), to deal
13 in the Software  without restriction, including without  limitation the rights
14 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 // XXX:
31 // Only compile these tests if 'float' and 'double' are IEEE-754 single- and
32 // double-precision numbers, resp.
33 
34 #include "doctest_compatibility.h"
35 
36 #include <nlohmann/json.hpp>
37 using nlohmann::detail::dtoa_impl::reinterpret_bits;
38 
39 namespace
40 {
make_float(uint32_t sign_bit,uint32_t biased_exponent,uint32_t significand)41 static float make_float(uint32_t sign_bit, uint32_t biased_exponent, uint32_t significand)
42 {
43     assert(sign_bit == 0 || sign_bit == 1);
44     assert(biased_exponent <= 0xFF);
45     assert(significand <= 0x007FFFFF);
46 
47     uint32_t bits = 0;
48 
49     bits |= sign_bit << 31;
50     bits |= biased_exponent << 23;
51     bits |= significand;
52 
53     return reinterpret_bits<float>(bits);
54 }
55 
56 // ldexp -- convert f * 2^e to IEEE single precision
make_float(uint64_t f,int e)57 static float make_float(uint64_t f, int e)
58 {
59     constexpr uint64_t kHiddenBit               = 0x00800000;
60     constexpr uint64_t kSignificandMask         = 0x007FFFFF;
61     constexpr int      kPhysicalSignificandSize = 23;  // Excludes the hidden bit.
62     constexpr int      kExponentBias            = 0x7F + kPhysicalSignificandSize;
63     constexpr int      kDenormalExponent        = 1 -    kExponentBias;
64     constexpr int      kMaxExponent             = 0xFF - kExponentBias;
65 
66     while (f > kHiddenBit + kSignificandMask)
67     {
68         f >>= 1;
69         e++;
70     }
71     if (e >= kMaxExponent)
72     {
73         return std::numeric_limits<float>::infinity();
74     }
75     if (e < kDenormalExponent)
76     {
77         return 0.0;
78     }
79     while (e > kDenormalExponent && (f & kHiddenBit) == 0)
80     {
81         f <<= 1;
82         e--;
83     }
84 
85     uint64_t biased_exponent = (e == kDenormalExponent && (f & kHiddenBit) == 0)
86                                ? 0
87                                : static_cast<uint64_t>(e + kExponentBias);
88 
89     uint64_t bits = (f & kSignificandMask) | (biased_exponent << kPhysicalSignificandSize);
90     return reinterpret_bits<float>(static_cast<uint32_t>(bits));
91 }
92 
make_double(uint64_t sign_bit,uint64_t biased_exponent,uint64_t significand)93 static double make_double(uint64_t sign_bit, uint64_t biased_exponent, uint64_t significand)
94 {
95     assert(sign_bit == 0 || sign_bit == 1);
96     assert(biased_exponent <= 0x7FF);
97     assert(significand <= 0x000FFFFFFFFFFFFF);
98 
99     uint64_t bits = 0;
100 
101     bits |= sign_bit << 63;
102     bits |= biased_exponent << 52;
103     bits |= significand;
104 
105     return reinterpret_bits<double>(bits);
106 }
107 
108 // ldexp -- convert f * 2^e to IEEE double precision
make_double(uint64_t f,int e)109 static double make_double(uint64_t f, int e)
110 {
111     constexpr uint64_t kHiddenBit               = 0x0010000000000000;
112     constexpr uint64_t kSignificandMask         = 0x000FFFFFFFFFFFFF;
113     constexpr int      kPhysicalSignificandSize = 52;  // Excludes the hidden bit.
114     constexpr int      kExponentBias            = 0x3FF + kPhysicalSignificandSize;
115     constexpr int      kDenormalExponent        = 1     - kExponentBias;
116     constexpr int      kMaxExponent             = 0x7FF - kExponentBias;
117 
118     while (f > kHiddenBit + kSignificandMask)
119     {
120         f >>= 1;
121         e++;
122     }
123     if (e >= kMaxExponent)
124     {
125         return std::numeric_limits<double>::infinity();
126     }
127     if (e < kDenormalExponent)
128     {
129         return 0.0;
130     }
131     while (e > kDenormalExponent && (f & kHiddenBit) == 0)
132     {
133         f <<= 1;
134         e--;
135     }
136 
137     uint64_t biased_exponent = (e == kDenormalExponent && (f & kHiddenBit) == 0)
138                                ? 0
139                                : static_cast<uint64_t>(e + kExponentBias);
140 
141     uint64_t bits = (f & kSignificandMask) | (biased_exponent << kPhysicalSignificandSize);
142     return reinterpret_bits<double>(bits);
143 }
144 }
145 
146 TEST_CASE("digit gen")
147 {
148     SECTION("single precision")
149     {
150         auto check_float = [](float number, const std::string & digits, int expected_exponent)
__anon3e05b3990202(float number, const std::string & digits, int expected_exponent) 151         {
152             CAPTURE(number)
153             CAPTURE(digits)
154             CAPTURE(expected_exponent)
155 
156             char buf[32];
157             int len = 0;
158             int exponent = 0;
159             nlohmann::detail::dtoa_impl::grisu2(buf, len, exponent, number);
160 
161             CHECK(digits == std::string(buf, buf + len));
162             CHECK(expected_exponent == exponent);
163         };
164 
165         check_float(make_float(0,   0, 0x00000001),        "1", -45); // min denormal
166         check_float(make_float(0,   0, 0x007FFFFF), "11754942", -45); // max denormal
167         check_float(make_float(0,   1, 0x00000000), "11754944", -45); // min normal
168         check_float(make_float(0,   1, 0x00000001), "11754945", -45);
169         check_float(make_float(0,   1, 0x007FFFFF), "23509886", -45);
170         check_float(make_float(0,   2, 0x00000000), "23509887", -45);
171         check_float(make_float(0,   2, 0x00000001),  "2350989", -44);
172         check_float(make_float(0,  24, 0x00000000), "98607613", -39); // fail if no special case in normalized boundaries
173         check_float(make_float(0,  30, 0x00000000), "63108872", -37); // fail if no special case in normalized boundaries
174         check_float(make_float(0,  31, 0x00000000), "12621775", -36); // fail if no special case in normalized boundaries
175         check_float(make_float(0,  57, 0x00000000), "84703295", -29); // fail if no special case in normalized boundaries
176         check_float(make_float(0, 254, 0x007FFFFE), "34028233",  31);
177         check_float(make_float(0, 254, 0x007FFFFF), "34028235",  31); // max normal
178 
179         // V. Paxson and W. Kahan, "A Program for Testing IEEE Binary-Decimal Conversion", manuscript, May 1991,
180         // ftp://ftp.ee.lbl.gov/testbase-report.ps.Z    (report)
181         // ftp://ftp.ee.lbl.gov/testbase.tar.Z          (program)
182 
183         // Table 16: Stress Inputs for Converting 24-bit Binary to Decimal, < 1/2 ULP
184         check_float(make_float(12676506, -102),       "25", -25);
185         check_float(make_float(12676506, -103),      "125", -26);
186         check_float(make_float(15445013,   86),     "1195",  30);
187         check_float(make_float(13734123, -138),    "39415", -39);
188         check_float(make_float(12428269, -130),   "913085", -38);
189         check_float(make_float(15334037, -146),  "1719005", -43);
190         check_float(make_float(11518287,  -41), "52379105", -13);
191         check_float(make_float(12584953, -145),  "2821644", -43);
192         check_float(make_float(15961084, -125), "37524328", -38);
193         check_float(make_float(14915817, -146), "16721209", -44);
194         check_float(make_float(10845484, -102), "21388946", -31);
195         check_float(make_float(16431059,  -61),  "7125836", -18);
196 
197         // Table 17: Stress Inputs for Converting 24-bit Binary to Decimal, > 1/2 ULP
198         check_float(make_float(16093626,   69),       "95",  26);
199         check_float(make_float( 9983778,   25),      "335",  12);
200         check_float(make_float(12745034,  104),     "2585",  35);
201         check_float(make_float(12706553,   72),    "60005",  24);
202         check_float(make_float(11005028,   45),   "387205",  15);
203         check_float(make_float(15059547,   71),  "3555835",  22);
204         check_float(make_float(16015691,  -99), "25268305", -30);
205         check_float(make_float( 8667859,   56),  "6245851",  17);
206         check_float(make_float(14855922,  -82), "30721327", -25);
207         check_float(make_float(14855922,  -83), "15360663", -25);
208         check_float(make_float(10144164, -110),   "781478", -32);
209         check_float(make_float(13248074,   95), "52481028",  28);
210     }
211 
212     SECTION("double precision")
213     {
214         auto check_double = [](double number, const std::string & digits, int expected_exponent)
__anon3e05b3990302(double number, const std::string & digits, int expected_exponent) 215         {
216             CAPTURE(number)
217             CAPTURE(digits)
218             CAPTURE(expected_exponent)
219 
220             char buf[32];
221             int len = 0;
222             int exponent = 0;
223             nlohmann::detail::dtoa_impl::grisu2(buf, len, exponent, number);
224 
225             CHECK(digits == std::string(buf, buf + len));
226             CHECK(expected_exponent == exponent);
227         };
228 
229         check_double(make_double(0,    0, 0x0000000000000001),                 "5", -324); // min denormal
230         check_double(make_double(0,    0, 0x000FFFFFFFFFFFFF),  "2225073858507201", -323); // max denormal
231         check_double(make_double(0,    1, 0x0000000000000000), "22250738585072014", -324); // min normal
232         check_double(make_double(0,    1, 0x0000000000000001),  "2225073858507202", -323);
233         check_double(make_double(0,    1, 0x000FFFFFFFFFFFFF), "44501477170144023", -324);
234         check_double(make_double(0,    2, 0x0000000000000000),  "4450147717014403", -323);
235         check_double(make_double(0,    2, 0x0000000000000001),  "4450147717014404", -323);
236         check_double(make_double(0,    4, 0x0000000000000000), "17800590868057611", -323); // fail if no special case in normalized boundaries
237         check_double(make_double(0,    5, 0x0000000000000000), "35601181736115222", -323); // fail if no special case in normalized boundaries
238         check_double(make_double(0,    6, 0x0000000000000000),  "7120236347223045", -322); // fail if no special case in normalized boundaries
239         check_double(make_double(0,   10, 0x0000000000000000), "11392378155556871", -321); // fail if no special case in normalized boundaries
240         check_double(make_double(0, 2046, 0x000FFFFFFFFFFFFE), "17976931348623155",  292);
241         check_double(make_double(0, 2046, 0x000FFFFFFFFFFFFF), "17976931348623157",  292); // max normal
242 
243         // Test different paths in DigitGen
244         check_double(                  10000,                 "1",    4);
245         check_double(                1200000,                "12",    5);
246         check_double(4.9406564584124654e-324,                 "5", -324); // exit integral loop
247         check_double(2.2250738585072009e-308,  "2225073858507201", -323); // exit fractional loop
248         check_double(   1.82877982605164e-99,   "182877982605164", -113);
249         check_double( 1.1505466208671903e-09, "11505466208671903",  -25);
250         check_double( 5.5645893133766722e+20,  "5564589313376672",    5);
251         check_double(     53.034830388866226, "53034830388866226",  -15);
252         check_double(  0.0021066531670178605, "21066531670178605",  -19);
253 
254         // V. Paxson and W. Kahan, "A Program for Testing IEEE Binary-Decimal Conversion", manuscript, May 1991,
255         // ftp://ftp.ee.lbl.gov/testbase-report.ps.Z    (report)
256         // ftp://ftp.ee.lbl.gov/testbase.tar.Z          (program)
257 
258         // Table 3: Stress Inputs for Converting 53-bit Binary to Decimal, < 1/2 ULP
259         check_double(make_double(8511030020275656,  -342) /*                9.5e-088 */,                "95",  -89);
260         check_double(make_double(5201988407066741,  -824) /*               4.65e-233 */,               "465", -235);
261         check_double(make_double(6406892948269899,  +237) /*              1.415e+087 */,              "1415",   84);
262         check_double(make_double(8431154198732492,   +72) /*             3.9815e+037 */,             "39815",   33);
263         check_double(make_double(6475049196144587,   +99) /*            4.10405e+045 */,            "410405",   40);
264         check_double(make_double(8274307542972842,  +726) /*           2.920845e+234 */,           "2920845",  228);
265         check_double(make_double(5381065484265332,  -456) /*          2.8919465e-122 */,          "28919465", -129);
266         check_double(make_double(6761728585499734, -1057) /*         4.37877185e-303 */,         "437877185", -311);
267         check_double(make_double(7976538478610756,  +376) /*        1.227701635e+129 */,        "1227701635",  120);
268         check_double(make_double(5982403858958067,  +377) /*       1.8415524525e+129 */,       "18415524525",  119);
269         check_double(make_double(5536995190630837,   +93) /*      5.48357443505e+043 */,      "548357443505",   32);
270         check_double(make_double(7225450889282194,  +710) /*     3.891901811465e+229 */,     "3891901811465",  217);
271         check_double(make_double(7225450889282194,  +709) /*    1.9459509057325e+229 */,    "19459509057325",  216);
272         check_double(make_double(8703372741147379,  +117) /*   1.44609583816055e+051 */,   "144609583816055",   37);
273         check_double(make_double(8944262675275217, -1001) /*  4.173677474585315e-286 */,  "4173677474585315", -301);
274         check_double(make_double(7459803696087692,  -707) /* 1.1079507728788885e-197 */, "11079507728788885", -213);
275         check_double(make_double(6080469016670379,  -381) /*  1.234550136632744e-099 */,  "1234550136632744", -114);
276         check_double(make_double(8385515147034757,  +721) /* 9.2503171196036502e+232 */,   "925031711960365",  218);
277         check_double(make_double(7514216811389786,  -828) /* 4.1980471502848898e-234 */,   "419804715028489", -248);
278         check_double(make_double(8397297803260511,  -345) /* 1.1716315319786511e-088 */, "11716315319786511", -104);
279         check_double(make_double(6733459239310543,  +202) /* 4.3281007284461249e+076 */,  "4328100728446125",   61);
280         check_double(make_double(8091450587292794,  -473) /* 3.3177101181600311e-127 */,  "3317710118160031", -142);
281 
282         // Table 4: Stress Inputs for Converting 53-bit Binary to Decimal, > 1/2 ULP
283         check_double(make_double(6567258882077402,  +952) /*                2.5e+302 */,                "25",  301);
284         check_double(make_double(6712731423444934,  +535) /*               7.55e+176 */,               "755",  174);
285         check_double(make_double(6712731423444934,  +534) /*              3.775e+176 */,              "3775",  173);
286         check_double(make_double(5298405411573037,  -957) /*             4.3495e-273 */,             "43495", -277);
287         check_double(make_double(5137311167659507,  -144) /*            2.30365e-028 */,            "230365",  -33);
288         check_double(make_double(6722280709661868,  +363) /*           1.263005e+125 */,           "1263005",  119);
289         check_double(make_double(5344436398034927,  -169) /*          7.1422105e-036 */,          "71422105",  -43);
290         check_double(make_double(8369123604277281,  -853) /*         1.39345735e-241 */,         "139345735", -249);
291         check_double(make_double(8995822108487663,  -780) /*        1.414634485e-219 */,        "1414634485", -228);
292         check_double(make_double(8942832835564782,  -383) /*       4.5392779195e-100 */,       "45392779195", -110);
293         check_double(make_double(8942832835564782,  -384) /*      2.26963895975e-100 */,      "226963895975", -111);
294         check_double(make_double(8942832835564782,  -385) /*     1.134819479875e-100 */,     "1134819479875", -112);
295         check_double(make_double(6965949469487146,  -249) /*    7.7003665618895e-060 */,    "77003665618895",  -73);
296         check_double(make_double(6965949469487146,  -250) /*   3.85018328094475e-060 */,   "385018328094475",  -74);
297         check_double(make_double(6965949469487146,  -251) /*  1.925091640472375e-060 */,  "1925091640472375",  -75);
298         check_double(make_double(7487252720986826,  +548) /* 6.8985865317742005e+180 */, "68985865317742005",  164);
299         check_double(make_double(5592117679628511,  +164) /* 1.3076622631878654e+065 */, "13076622631878654",   49);
300         check_double(make_double(8887055249355788,  +665) /* 1.3605202075612124e+216 */, "13605202075612124",  200);
301         check_double(make_double(6994187472632449,  +690) /* 3.5928102174759597e+223 */, "35928102174759597",  207);
302         check_double(make_double(8797576579012143,  +588) /* 8.9125197712484552e+192 */,  "8912519771248455",  177);
303         check_double(make_double(7363326733505337,  +272) /* 5.5876975736230114e+097 */, "55876975736230114",   81);
304         check_double(make_double(8549497411294502,  -448) /* 1.1762578307285404e-119 */, "11762578307285404", -135);
305 
306         // Table 20: Stress Inputs for Converting 56-bit Binary to Decimal, < 1/2 ULP
307         check_double(make_double(50883641005312716, -172) /* 8.4999999999999993e-036 */,  "8499999999999999",  -51);
308         check_double(make_double(38162730753984537, -170) /* 2.5499999999999999e-035 */,               "255",  -37);
309         check_double(make_double(50832789069151999, -101) /* 2.0049999999999997e-014 */, "20049999999999997",  -30);
310         check_double(make_double(51822367833714164, -109) /* 7.9844999999999994e-017 */,  "7984499999999999",  -32);
311         check_double(make_double(66840152193508133, -172) /* 1.1165499999999999e-035 */, "11165499999999999",  -51);
312         check_double(make_double(55111239245584393, -138) /*           1.581615e-025 */,           "1581615",  -31);
313         check_double(make_double(71704866733321482, -112) /*          1.3809855e-017 */,          "13809855",  -24);
314         check_double(make_double(67160949328233173, -142) /* 1.2046404499999999e-026 */, "12046404499999999",  -42);
315         check_double(make_double(53237141308040189, -152) /* 9.3251405449999991e-030 */,  "9325140544999999",  -45);
316         check_double(make_double(62785329394975786, -112) /*       1.2092014595e-017 */,       "12092014595",  -27);
317         check_double(make_double(48367680154689523,  -77) /* 3.2007045838499998e-007 */,      "320070458385",  -18);
318         check_double(make_double(42552223180606797, -102) /*  8.391946324354999e-015 */,  "8391946324354999",  -30);
319         check_double(make_double(63626356173011241, -112) /*    1.2253990460585e-017 */,    "12253990460585",  -30);
320         check_double(make_double(43566388595783643,  -99) /* 6.8735641489760495e-014 */,   "687356414897605",  -28);
321         check_double(make_double(54512669636675272, -159) /*  7.459816430480385e-032 */,  "7459816430480385",  -47);
322         check_double(make_double(52306490527514614, -167) /* 2.7960588398142552e-034 */,  "2796058839814255",  -49);
323         check_double(make_double(52306490527514614, -168) /* 1.3980294199071276e-034 */, "13980294199071276",  -50);
324         check_double(make_double(41024721590449423,  -89) /* 6.6279012373057359e-011 */,  "6627901237305736",  -26);
325         check_double(make_double(37664020415894738, -132) /* 6.9177880043968072e-024 */,  "6917788004396807",  -39);
326         check_double(make_double(37549883692866294,  -93) /* 3.7915693108349708e-012 */,  "3791569310834971",  -27);
327         check_double(make_double(69124110374399839, -104) /* 3.4080817676591365e-015 */, "34080817676591365",  -31);
328         check_double(make_double(69124110374399839, -105) /* 1.7040408838295683e-015 */, "17040408838295683",  -31);
329 
330         // Table 21: Stress Inputs for Converting 56-bit Binary to Decimal, > 1/2 ULP
331         check_double(make_double(49517601571415211,  -94) /* 2.4999999999999998e-012 */,                "25",  -13);
332         check_double(make_double(49517601571415211,  -95) /* 1.2499999999999999e-012 */,               "125",  -14);
333         check_double(make_double(54390733528642804, -133) /* 4.9949999999999996e-024 */, "49949999999999996",  -40); // shortest: 4995e-27
334         check_double(make_double(71805402319113924, -157) /* 3.9304999999999998e-031 */, "39304999999999998",  -47); // shortest: 39305e-35
335         check_double(make_double(40435277969631694, -179) /* 5.2770499999999992e-038 */,  "5277049999999999",  -53);
336         check_double(make_double(57241991568619049, -165) /*           1.223955e-033 */,           "1223955",  -39);
337         check_double(make_double(65224162876242886,  +58) /* 1.8799584999999998e+034 */, "18799584999999998",   18);
338         check_double(make_double(70173376848895368, -138) /*         2.01387715e-025 */,         "201387715",  -33);
339         check_double(make_double(37072848117383207,  -99) /* 5.8490641049999989e-014 */,  "5849064104999999",  -29);
340         check_double(make_double(56845051585389697, -176) /* 5.9349003054999999e-037 */,       "59349003055",  -47);
341         check_double(make_double(54791673366936431, -145) /* 1.2284718039499998e-027 */, "12284718039499998",  -43);
342         check_double(make_double(66800318669106231, -169) /* 8.9270767180849991e-035 */,  "8927076718084999",  -50);
343         check_double(make_double(66800318669106231, -170) /* 4.4635383590424995e-035 */, "44635383590424995",  -51);
344         check_double(make_double(66574323440112438, -119) /* 1.0016990862549499e-019 */, "10016990862549499",  -35);
345         check_double(make_double(65645179969330963, -173) /* 5.4829412628024647e-036 */,  "5482941262802465",  -51);
346         check_double(make_double(61847254334681076, -109) /* 9.5290783281036439e-017 */,  "9529078328103644",  -32);
347         check_double(make_double(39990712921393606, -145) /* 8.9662279366405553e-028 */,  "8966227936640555",  -43);
348         check_double(make_double(59292318184400283, -149) /* 8.3086234418058538e-029 */,  "8308623441805854",  -44);
349         check_double(make_double(69116558615326153, -143) /* 6.1985873566126555e-027 */, "61985873566126555",  -43);
350         check_double(make_double(69116558615326153, -144) /* 3.0992936783063277e-027 */, "30992936783063277",  -43);
351         check_double(make_double(39462549494468513, -152) /* 6.9123512506176015e-030 */,  "6912351250617602",  -45);
352         check_double(make_double(39462549494468513, -153) /* 3.4561756253088008e-030 */,  "3456175625308801",  -45);
353     }
354 }
355 
356 TEST_CASE("formatting")
357 {
358     SECTION("single precision")
359     {
360         auto check_float = [](float number, const std::string & expected)
__anon3e05b3990402(float number, const std::string & expected) 361         {
362             std::array<char, 33> buf{};
363             char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number);
364             std::string actual(buf.data(), end);
365 
366             CHECK(actual == expected);
367         };
368         // %.9g
369         check_float( -1.2345e-22f, "-1.2345e-22"  ); // -1.23450004e-22
370         check_float( -1.2345e-21f, "-1.2345e-21"  ); // -1.23450002e-21
371         check_float( -1.2345e-20f, "-1.2345e-20"  ); // -1.23450002e-20
372         check_float( -1.2345e-19f, "-1.2345e-19"  ); // -1.23449999e-19
373         check_float( -1.2345e-18f, "-1.2345e-18"  ); // -1.23449996e-18
374         check_float( -1.2345e-17f, "-1.2345e-17"  ); // -1.23449998e-17
375         check_float( -1.2345e-16f, "-1.2345e-16"  ); // -1.23449996e-16
376         check_float( -1.2345e-15f, "-1.2345e-15"  ); // -1.23450002e-15
377         check_float( -1.2345e-14f, "-1.2345e-14"  ); // -1.23450004e-14
378         check_float( -1.2345e-13f, "-1.2345e-13"  ); // -1.23449997e-13
379         check_float( -1.2345e-12f, "-1.2345e-12"  ); // -1.23450002e-12
380         check_float( -1.2345e-11f, "-1.2345e-11"  ); // -1.2345e-11
381         check_float( -1.2345e-10f, "-1.2345e-10"  ); // -1.2345e-10
382         check_float( -1.2345e-9f,  "-1.2345e-09"  ); // -1.23449995e-09
383         check_float( -1.2345e-8f,  "-1.2345e-08"  ); // -1.23449997e-08
384         check_float( -1.2345e-7f,  "-1.2345e-07"  ); // -1.23449993e-07
385         check_float( -1.2345e-6f,  "-1.2345e-06"  ); // -1.23450002e-06
386         check_float( -1.2345e-5f,  "-1.2345e-05"  ); // -1.2345e-05
387         check_float( -1.2345e-4f,  "-0.00012345"  ); // -0.000123449994
388         check_float( -1.2345e-3f,  "-0.0012345"   ); // -0.00123449997
389         check_float( -1.2345e-2f,  "-0.012345"    ); // -0.0123450002
390         check_float( -1.2345e-1f,  "-0.12345"     ); // -0.123450004
391         check_float( -0.0f,        "-0.0"         ); // -0
392         check_float(  0.0f,         "0.0"         ); //  0
393         check_float(  1.2345e+0f,   "1.2345"      ); //  1.23450005
394         check_float(  1.2345e+1f,   "12.345"      ); //  12.3450003
395         check_float(  1.2345e+2f,   "123.45"      ); //  123.449997
396         check_float(  1.2345e+3f,   "1234.5"      ); //  1234.5
397         check_float(  1.2345e+4f,   "12345.0"     ); //  12345
398         check_float(  1.2345e+5f,   "123450.0"    ); //  123450
399         check_float(  1.2345e+6f,   "1.2345e+06"  ); //  1234500
400         check_float(  1.2345e+7f,   "1.2345e+07"  ); //  12345000
401         check_float(  1.2345e+8f,   "1.2345e+08"  ); //  123450000
402         check_float(  1.2345e+9f,   "1.2345e+09"  ); //  1.23449997e+09
403         check_float(  1.2345e+10f,  "1.2345e+10"  ); //  1.23449999e+10
404         check_float(  1.2345e+11f,  "1.2345e+11"  ); //  1.23449999e+11
405         check_float(  1.2345e+12f,  "1.2345e+12"  ); //  1.23450006e+12
406         check_float(  1.2345e+13f,  "1.2345e+13"  ); //  1.23449995e+13
407         check_float(  1.2345e+14f,  "1.2345e+14"  ); //  1.23450002e+14
408         check_float(  1.2345e+15f,  "1.2345e+15"  ); //  1.23450003e+15
409         check_float(  1.2345e+16f,  "1.2345e+16"  ); //  1.23449998e+16
410         check_float(  1.2345e+17f,  "1.2345e+17"  ); //  1.23449996e+17
411         check_float(  1.2345e+18f,  "1.2345e+18"  ); //  1.23450004e+18
412         check_float(  1.2345e+19f,  "1.2345e+19"  ); //  1.23449999e+19
413         check_float(  1.2345e+20f,  "1.2345e+20"  ); //  1.23449999e+20
414         check_float(  1.2345e+21f,  "1.2345e+21"  ); //  1.23449999e+21
415         check_float(  1.2345e+22f,  "1.2345e+22"  ); //  1.23450005e+22
416     }
417 
418     SECTION("double precision")
419     {
420         auto check_double = [](double number, const std::string & expected)
__anon3e05b3990502(double number, const std::string & expected) 421         {
422             std::array<char, 33> buf{};
423             char* end = nlohmann::detail::to_chars(buf.data(), buf.data() + 32, number);
424             std::string actual(buf.data(), end);
425 
426             CHECK(actual == expected);
427         };
428         //                           dtoa                           %.15g                     %.17g                     shortest
429         check_double( -1.2345e-22,  "-1.2345e-22"             ); // -1.2345e-22               -1.2345000000000001e-22   -1.2345e-22
430         check_double( -1.2345e-21,  "-1.2345e-21"             ); // -1.2345e-21               -1.2345000000000001e-21   -1.2345e-21
431         check_double( -1.2345e-20,  "-1.2345e-20"             ); // -1.2345e-20               -1.2345e-20               -1.2345e-20
432         check_double( -1.2345e-19,  "-1.2345e-19"             ); // -1.2345e-19               -1.2345000000000001e-19   -1.2345e-19
433         check_double( -1.2345e-18,  "-1.2345e-18"             ); // -1.2345e-18               -1.2345000000000001e-18   -1.2345e-18
434         check_double( -1.2345e-17,  "-1.2345e-17"             ); // -1.2345e-17               -1.2345e-17               -1.2345e-17
435         check_double( -1.2345e-16,  "-1.2345e-16"             ); // -1.2345e-16               -1.2344999999999999e-16   -1.2345e-16
436         check_double( -1.2345e-15,  "-1.2345e-15"             ); // -1.2345e-15               -1.2345e-15               -1.2345e-15
437         check_double( -1.2345e-14,  "-1.2345e-14"             ); // -1.2345e-14               -1.2345e-14               -1.2345e-14
438         check_double( -1.2345e-13,  "-1.2345e-13"             ); // -1.2345e-13               -1.2344999999999999e-13   -1.2345e-13
439         check_double( -1.2345e-12,  "-1.2345e-12"             ); // -1.2345e-12               -1.2345e-12               -1.2345e-12
440         check_double( -1.2345e-11,  "-1.2345e-11"             ); // -1.2345e-11               -1.2345e-11               -1.2345e-11
441         check_double( -1.2345e-10,  "-1.2345e-10"             ); // -1.2345e-10               -1.2345e-10               -1.2345e-10
442         check_double( -1.2345e-9,   "-1.2345e-09"             ); // -1.2345e-09               -1.2345e-09               -1.2345e-9
443         check_double( -1.2345e-8,   "-1.2345e-08"             ); // -1.2345e-08               -1.2345000000000001e-08   -1.2345e-8
444         check_double( -1.2345e-7,   "-1.2345e-07"             ); // -1.2345e-07               -1.2345000000000001e-07   -1.2345e-7
445         check_double( -1.2345e-6,   "-1.2345e-06"             ); // -1.2345e-06               -1.2345e-06               -1.2345e-6
446         check_double( -1.2345e-5,   "-1.2345e-05"             ); // -1.2345e-05               -1.2345e-05               -1.2345e-5
447         check_double( -1.2345e-4,   "-0.00012345"             ); // -0.00012345               -0.00012344999999999999   -0.00012345
448         check_double( -1.2345e-3,   "-0.0012345"              ); // -0.0012345                -0.0012344999999999999    -0.0012345
449         check_double( -1.2345e-2,   "-0.012345"               ); // -0.012345                 -0.012345                 -0.012345
450         check_double( -1.2345e-1,   "-0.12345"                ); // -0.12345                  -0.12345                  -0.12345
451         check_double( -0.0,         "-0.0"                    ); // -0                        -0                        -0
452         check_double(  0.0,          "0.0"                    ); //  0                         0                         0
453         check_double(  1.2345e+0,    "1.2345"                 ); //  1.2345                    1.2344999999999999        1.2345
454         check_double(  1.2345e+1,    "12.345"                 ); //  12.345                    12.345000000000001        12.345
455         check_double(  1.2345e+2,    "123.45"                 ); //  123.45                    123.45                    123.45
456         check_double(  1.2345e+3,    "1234.5"                 ); //  1234.5                    1234.5                    1234.5
457         check_double(  1.2345e+4,    "12345.0"                ); //  12345                     12345                     12345
458         check_double(  1.2345e+5,    "123450.0"               ); //  123450                    123450                    123450
459         check_double(  1.2345e+6,    "1234500.0"              ); //  1234500                   1234500                   1234500
460         check_double(  1.2345e+7,    "12345000.0"             ); //  12345000                  12345000                  12345000
461         check_double(  1.2345e+8,    "123450000.0"            ); //  123450000                 123450000                 123450000
462         check_double(  1.2345e+9,    "1234500000.0"           ); //  1234500000                1234500000                1234500000
463         check_double(  1.2345e+10,   "12345000000.0"          ); //  12345000000               12345000000               12345000000
464         check_double(  1.2345e+11,   "123450000000.0"         ); //  123450000000              123450000000              123450000000
465         check_double(  1.2345e+12,   "1234500000000.0"        ); //  1234500000000             1234500000000             1234500000000
466         check_double(  1.2345e+13,   "12345000000000.0"       ); //  12345000000000            12345000000000            12345000000000
467         check_double(  1.2345e+14,   "123450000000000.0"      ); //  123450000000000           123450000000000           123450000000000
468         check_double(  1.2345e+15,   "1.2345e+15"             ); //  1.2345e+15                1234500000000000          1.2345e15
469         check_double(  1.2345e+16,   "1.2345e+16"             ); //  1.2345e+16                12345000000000000         1.2345e16
470         check_double(  1.2345e+17,   "1.2345e+17"             ); //  1.2345e+17                1.2345e+17                1.2345e17
471         check_double(  1.2345e+18,   "1.2345e+18"             ); //  1.2345e+18                1.2345e+18                1.2345e18
472         check_double(  1.2345e+19,   "1.2345e+19"             ); //  1.2345e+19                1.2345e+19                1.2345e19
473         check_double(  1.2345e+20,   "1.2345e+20"             ); //  1.2345e+20                1.2345e+20                1.2345e20
474         check_double(  1.2345e+21,   "1.2344999999999999e+21" ); //  1.2345e+21                1.2344999999999999e+21    1.2345e21
475         check_double(  1.2345e+22,   "1.2345e+22"             ); //  1.2345e+22                1.2345e+22                1.2345e22
476     }
477 
478     SECTION("integer")
479     {
480         auto check_integer = [](std::int64_t number, const std::string & expected)
__anon3e05b3990602(std::int64_t number, const std::string & expected) 481         {
482             nlohmann::json j = number;
483             CHECK(j.dump() == expected);
484         };
485 
486         // edge cases
487         check_integer(INT64_MIN, "-9223372036854775808");
488         check_integer(INT64_MAX, "9223372036854775807");
489 
490         // few random big integers
491         check_integer(-3456789012345678901LL, "-3456789012345678901");
492         check_integer(3456789012345678901LL, "3456789012345678901");
493         check_integer(-5678901234567890123LL, "-5678901234567890123");
494         check_integer(5678901234567890123LL, "5678901234567890123");
495 
496         // integers with various digit counts
497         check_integer(-1000000000000000000LL, "-1000000000000000000");
498         check_integer(-100000000000000000LL, "-100000000000000000");
499         check_integer(-10000000000000000LL, "-10000000000000000");
500         check_integer(-1000000000000000LL, "-1000000000000000");
501         check_integer(-100000000000000LL, "-100000000000000");
502         check_integer(-10000000000000LL, "-10000000000000");
503         check_integer(-1000000000000LL, "-1000000000000");
504         check_integer(-100000000000LL, "-100000000000");
505         check_integer(-10000000000LL, "-10000000000");
506         check_integer(-1000000000LL, "-1000000000");
507         check_integer(-100000000LL, "-100000000");
508         check_integer(-10000000LL, "-10000000");
509         check_integer(-1000000LL, "-1000000");
510         check_integer(-100000LL, "-100000");
511         check_integer(-10000LL, "-10000");
512         check_integer(-1000LL, "-1000");
513         check_integer(-100LL, "-100");
514         check_integer(-10LL, "-10");
515         check_integer(-1LL, "-1");
516         check_integer(0, "0");
517         check_integer(1LL, "1");
518         check_integer(10LL, "10");
519         check_integer(100LL, "100");
520         check_integer(1000LL, "1000");
521         check_integer(10000LL, "10000");
522         check_integer(100000LL, "100000");
523         check_integer(1000000LL, "1000000");
524         check_integer(10000000LL, "10000000");
525         check_integer(100000000LL, "100000000");
526         check_integer(1000000000LL, "1000000000");
527         check_integer(10000000000LL, "10000000000");
528         check_integer(100000000000LL, "100000000000");
529         check_integer(1000000000000LL, "1000000000000");
530         check_integer(10000000000000LL, "10000000000000");
531         check_integer(100000000000000LL, "100000000000000");
532         check_integer(1000000000000000LL, "1000000000000000");
533         check_integer(10000000000000000LL, "10000000000000000");
534         check_integer(100000000000000000LL, "100000000000000000");
535         check_integer(1000000000000000000LL, "1000000000000000000");
536     }
537 }
538