1 // Copyright (c) Microsoft Corporation.
2 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3 
4 
5 // Copyright 2018 Ulf Adams
6 // Copyright (c) Microsoft Corporation. All rights reserved.
7 
8 // Boost Software License - Version 1.0 - August 17th, 2003
9 
10 // Permission is hereby granted, free of charge, to any person or organization
11 // obtaining a copy of the software and accompanying documentation covered by
12 // this license (the "Software") to use, reproduce, display, distribute,
13 // execute, and transmit the Software, and to prepare derivative works of the
14 // Software, and to permit third-parties to whom the Software is furnished to
15 // do so, all subject to the following:
16 
17 // The copyright notices in the Software and this entire statement, including
18 // the above license grant, this restriction and the following disclaimer,
19 // must be included in all copies of the Software, in whole or in part, and
20 // all derivative works of the Software, unless such copies or derivative
21 // works are solely in the form of machine-executable object code generated by
22 // a source language processor.
23 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
27 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
28 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
29 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 
32 
33 // This file contains test cases derived from:
34 // https://github.com/ulfjack/ryu
35 // See xcharconv_ryu.h for the exact commit.
36 // (Keep the cgmanifest.json commitHash in sync.)
37 
38 
39 #ifndef FLOAT_TO_CHARS_TEST_CASES_HPP
40 #define FLOAT_TO_CHARS_TEST_CASES_HPP
41 
42 #include <charconv>
43 
44 #include "test.hpp"
45 using namespace std;
46 
47 inline constexpr FloatToCharsTestCase float_to_chars_test_cases[] = {
48     // Test special cases (zero, inf, nan) and an ordinary case. Also test negative signs.
49     {0.0f, chars_format::scientific, "0e+00"},
50     {-0.0f, chars_format::scientific, "-0e+00"},
51     {float_inf, chars_format::scientific, "inf"},
52     {-float_inf, chars_format::scientific, "-inf"},
53     {float_nan, chars_format::scientific, "nan"},
54     {-float_nan, chars_format::scientific, "-nan(ind)"},
55     {float_nan_payload, chars_format::scientific, "nan"},
56     {-float_nan_payload, chars_format::scientific, "-nan"},
57     {2.018f, chars_format::scientific, "2.018e+00"},
58     {-2.018f, chars_format::scientific, "-2.018e+00"},
59 
60     // Ditto for fixed, which doesn't emit exponents.
61     {0.0f, chars_format::fixed, "0"},
62     {-0.0f, chars_format::fixed, "-0"},
63     {float_inf, chars_format::fixed, "inf"},
64     {-float_inf, chars_format::fixed, "-inf"},
65     {float_nan, chars_format::fixed, "nan"},
66     {-float_nan, chars_format::fixed, "-nan(ind)"},
67     {float_nan_payload, chars_format::fixed, "nan"},
68     {-float_nan_payload, chars_format::fixed, "-nan"},
69     {2.018f, chars_format::fixed, "2.018"},
70     {-2.018f, chars_format::fixed, "-2.018"},
71 
72     // Ditto for general, which selects fixed for the scientific exponent 0.
73     {0.0f, chars_format::general, "0"},
74     {-0.0f, chars_format::general, "-0"},
75     {float_inf, chars_format::general, "inf"},
76     {-float_inf, chars_format::general, "-inf"},
77     {float_nan, chars_format::general, "nan"},
78     {-float_nan, chars_format::general, "-nan(ind)"},
79     {float_nan_payload, chars_format::general, "nan"},
80     {-float_nan_payload, chars_format::general, "-nan"},
81     {2.018f, chars_format::general, "2.018"},
82     {-2.018f, chars_format::general, "-2.018"},
83 
84     // Ditto for plain, which selects fixed because it's shorter for these values.
85     {0.0f, chars_format{}, "0"},
86     {-0.0f, chars_format{}, "-0"},
87     {float_inf, chars_format{}, "inf"},
88     {-float_inf, chars_format{}, "-inf"},
89     {float_nan, chars_format{}, "nan"},
90     {-float_nan, chars_format{}, "-nan(ind)"},
91     {float_nan_payload, chars_format{}, "nan"},
92     {-float_nan_payload, chars_format{}, "-nan"},
93     {2.018f, chars_format{}, "2.018"},
94     {-2.018f, chars_format{}, "-2.018"},
95 
96     // Ditto for hex.
97     {0.0f, chars_format::hex, "0p+0"},
98     {-0.0f, chars_format::hex, "-0p+0"},
99     {float_inf, chars_format::hex, "inf"},
100     {-float_inf, chars_format::hex, "-inf"},
101     {float_nan, chars_format::hex, "nan"},
102     {-float_nan, chars_format::hex, "-nan(ind)"},
103     {float_nan_payload, chars_format::hex, "nan"},
104     {-float_nan_payload, chars_format::hex, "-nan"},
105     {0x1.729p+0f, chars_format::hex, "1.729p+0"},
106     {-0x1.729p+0f, chars_format::hex, "-1.729p+0"},
107 
108     // Ryu f2s_test.cc SwitchToSubnormal
109     {1.1754944e-38f, chars_format::scientific, "1.1754944e-38"},
110 
111     // Ryu f2s_test.cc MinAndMax
112     {0x1.fffffep+127f, chars_format::scientific, "3.4028235e+38"},
113     {0x1.000000p-149f, chars_format::scientific, "1e-45"},
114 
115     // Ryu f2s_test.cc BoundaryRoundEven
116     {3.355445e7f, chars_format::scientific, "3.355445e+07"},
117     {8.999999e9f, chars_format::scientific, "9e+09"},
118     {3.4366717e10f, chars_format::scientific, "3.436672e+10"},
119 
120     // Ryu f2s_test.cc ExactValueRoundEven
121     {3.0540412e5f, chars_format::scientific, "3.0540412e+05"},
122     {8.0990312e3f, chars_format::scientific, "8.0990312e+03"},
123 
124     // Ryu f2s_test.cc LotsOfTrailingZeros
125     {2.4414062e-4f, chars_format::scientific, "2.4414062e-04"},
126     {2.4414062e-3f, chars_format::scientific, "2.4414062e-03"},
127     {4.3945312e-3f, chars_format::scientific, "4.3945312e-03"},
128     {6.3476562e-3f, chars_format::scientific, "6.3476562e-03"},
129 
130     // Ryu f2s_test.cc Regression
131     {4.7223665e21f, chars_format::scientific, "4.7223665e+21"},
132     {8388608.0f, chars_format::scientific, "8.388608e+06"},
133     {1.6777216e7f, chars_format::scientific, "1.6777216e+07"},
134     {3.3554436e7f, chars_format::scientific, "3.3554436e+07"},
135     {6.7131496e7f, chars_format::scientific, "6.7131496e+07"},
136     {1.9310392e-38f, chars_format::scientific, "1.9310392e-38"},
137     {-2.47e-43f, chars_format::scientific, "-2.47e-43"},
138     {1.993244e-38f, chars_format::scientific, "1.993244e-38"},
139     {4103.9003f, chars_format::scientific, "4.1039004e+03"},
140     {5.3399997e9f, chars_format::scientific, "5.3399997e+09"},
141     {6.0898e-39f, chars_format::scientific, "6.0898e-39"},
142     {0.0010310042f, chars_format::scientific, "1.0310042e-03"},
143     {2.8823261e17f, chars_format::scientific, "2.882326e+17"},
144     {0x1.5c87fap-84f, chars_format::scientific, "7.038531e-26"}, // TRANSITION, VSO-629490, should be 7.038531e-26f
145     {9.2234038e17f, chars_format::scientific, "9.223404e+17"},
146     {6.7108872e7f, chars_format::scientific, "6.710887e+07"},
147     {1.0e-44f, chars_format::scientific, "1e-44"},
148     {2.816025e14f, chars_format::scientific, "2.816025e+14"},
149     {9.223372e18f, chars_format::scientific, "9.223372e+18"},
150     {1.5846085e29f, chars_format::scientific, "1.5846086e+29"},
151     {1.1811161e19f, chars_format::scientific, "1.1811161e+19"},
152     {5.368709e18f, chars_format::scientific, "5.368709e+18"},
153     {4.6143165e18f, chars_format::scientific, "4.6143166e+18"},
154     {0.007812537f, chars_format::scientific, "7.812537e-03"},
155     {1.4e-45f, chars_format::scientific, "1e-45"},
156     {1.18697724e20f, chars_format::scientific, "1.18697725e+20"},
157     {1.00014165e-36f, chars_format::scientific, "1.00014165e-36"},
158     {200.0f, chars_format::scientific, "2e+02"},
159     {3.3554432e7f, chars_format::scientific, "3.3554432e+07"},
160 
161     // Ryu f2s_test.cc LooksLikePow5
162     {0x1.2a05f2p+59f, chars_format::scientific, "6.7108864e+17"},
163     {0x1.2a05f2p+60f, chars_format::scientific, "1.3421773e+18"},
164     {0x1.2a05f2p+61f, chars_format::scientific, "2.6843546e+18"},
165 
166     // Ryu f2s_test.cc OutputLength
167     {1.0f, chars_format::scientific, "1e+00"},
168     {1.2f, chars_format::scientific, "1.2e+00"},
169     {1.23f, chars_format::scientific, "1.23e+00"},
170     {1.234f, chars_format::scientific, "1.234e+00"},
171     {1.2345f, chars_format::scientific, "1.2345e+00"},
172     {1.23456f, chars_format::scientific, "1.23456e+00"},
173     {1.234567f, chars_format::scientific, "1.234567e+00"},
174     {1.2345678f, chars_format::scientific, "1.2345678e+00"},
175     {1.23456735e-36f, chars_format::scientific, "1.23456735e-36"},
176 
177     // Test all exponents.
178     {1.729e-45f, chars_format::scientific, "1e-45"},
179     {1.729e-44f, chars_format::scientific, "1.7e-44"},
180     {1.729e-43f, chars_format::scientific, "1.72e-43"},
181     {1.729e-42f, chars_format::scientific, "1.729e-42"},
182     {1.729e-41f, chars_format::scientific, "1.729e-41"},
183     {1.729e-40f, chars_format::scientific, "1.729e-40"},
184     {1.729e-39f, chars_format::scientific, "1.729e-39"},
185     {1.729e-38f, chars_format::scientific, "1.729e-38"},
186     {1.729e-37f, chars_format::scientific, "1.729e-37"},
187     {1.729e-36f, chars_format::scientific, "1.729e-36"},
188     {1.729e-35f, chars_format::scientific, "1.729e-35"},
189     {1.729e-34f, chars_format::scientific, "1.729e-34"},
190     {1.729e-33f, chars_format::scientific, "1.729e-33"},
191     {1.729e-32f, chars_format::scientific, "1.729e-32"},
192     {1.729e-31f, chars_format::scientific, "1.729e-31"},
193     {1.729e-30f, chars_format::scientific, "1.729e-30"},
194     {1.729e-29f, chars_format::scientific, "1.729e-29"},
195     {1.729e-28f, chars_format::scientific, "1.729e-28"},
196     {1.729e-27f, chars_format::scientific, "1.729e-27"},
197     {1.729e-26f, chars_format::scientific, "1.729e-26"},
198     {1.729e-25f, chars_format::scientific, "1.729e-25"},
199     {1.729e-24f, chars_format::scientific, "1.729e-24"},
200     {1.729e-23f, chars_format::scientific, "1.729e-23"},
201     {1.729e-22f, chars_format::scientific, "1.729e-22"},
202     {1.729e-21f, chars_format::scientific, "1.729e-21"},
203     {1.729e-20f, chars_format::scientific, "1.729e-20"},
204     {1.729e-19f, chars_format::scientific, "1.729e-19"},
205     {1.729e-18f, chars_format::scientific, "1.729e-18"},
206     {1.729e-17f, chars_format::scientific, "1.729e-17"},
207     {1.729e-16f, chars_format::scientific, "1.729e-16"},
208     {1.729e-15f, chars_format::scientific, "1.729e-15"},
209     {1.729e-14f, chars_format::scientific, "1.729e-14"},
210     {1.729e-13f, chars_format::scientific, "1.729e-13"},
211     {1.729e-12f, chars_format::scientific, "1.729e-12"},
212     {1.729e-11f, chars_format::scientific, "1.729e-11"},
213     {1.729e-10f, chars_format::scientific, "1.729e-10"},
214     {1.729e-9f, chars_format::scientific, "1.729e-09"},
215     {1.729e-8f, chars_format::scientific, "1.729e-08"},
216     {1.729e-7f, chars_format::scientific, "1.729e-07"},
217     {1.729e-6f, chars_format::scientific, "1.729e-06"},
218     {1.729e-5f, chars_format::scientific, "1.729e-05"},
219     {1.729e-4f, chars_format::scientific, "1.729e-04"},
220     {1.729e-3f, chars_format::scientific, "1.729e-03"},
221     {1.729e-2f, chars_format::scientific, "1.729e-02"},
222     {1.729e-1f, chars_format::scientific, "1.729e-01"},
223     {1.729e0f, chars_format::scientific, "1.729e+00"},
224     {1.729e1f, chars_format::scientific, "1.729e+01"},
225     {1.729e2f, chars_format::scientific, "1.729e+02"},
226     {1.729e3f, chars_format::scientific, "1.729e+03"},
227     {1.729e4f, chars_format::scientific, "1.729e+04"},
228     {1.729e5f, chars_format::scientific, "1.729e+05"},
229     {1.729e6f, chars_format::scientific, "1.729e+06"},
230     {1.729e7f, chars_format::scientific, "1.729e+07"},
231     {1.729e8f, chars_format::scientific, "1.729e+08"},
232     {1.729e9f, chars_format::scientific, "1.729e+09"},
233     {1.729e10f, chars_format::scientific, "1.729e+10"},
234     {1.729e11f, chars_format::scientific, "1.729e+11"},
235     {1.729e12f, chars_format::scientific, "1.729e+12"},
236     {1.729e13f, chars_format::scientific, "1.729e+13"},
237     {1.729e14f, chars_format::scientific, "1.729e+14"},
238     {1.729e15f, chars_format::scientific, "1.729e+15"},
239     {1.729e16f, chars_format::scientific, "1.729e+16"},
240     {1.729e17f, chars_format::scientific, "1.729e+17"},
241     {1.729e18f, chars_format::scientific, "1.729e+18"},
242     {1.729e19f, chars_format::scientific, "1.729e+19"},
243     {1.729e20f, chars_format::scientific, "1.729e+20"},
244     {1.729e21f, chars_format::scientific, "1.729e+21"},
245     {1.729e22f, chars_format::scientific, "1.729e+22"},
246     {1.729e23f, chars_format::scientific, "1.729e+23"},
247     {1.729e24f, chars_format::scientific, "1.729e+24"},
248     {1.729e25f, chars_format::scientific, "1.729e+25"},
249     {1.729e26f, chars_format::scientific, "1.729e+26"},
250     {1.729e27f, chars_format::scientific, "1.729e+27"},
251     {1.729e28f, chars_format::scientific, "1.729e+28"},
252     {1.729e29f, chars_format::scientific, "1.729e+29"},
253     {1.729e30f, chars_format::scientific, "1.729e+30"},
254     {1.729e31f, chars_format::scientific, "1.729e+31"},
255     {1.729e32f, chars_format::scientific, "1.729e+32"},
256     {1.729e33f, chars_format::scientific, "1.729e+33"},
257     {1.729e34f, chars_format::scientific, "1.729e+34"},
258     {1.729e35f, chars_format::scientific, "1.729e+35"},
259     {1.729e36f, chars_format::scientific, "1.729e+36"},
260     {1.729e37f, chars_format::scientific, "1.729e+37"},
261     {1.729e38f, chars_format::scientific, "1.729e+38"},
262 
263     // Test all of the cases for fixed notation, including the non-Ryu fallback for large integers.
264     {1.729e-4f, chars_format::fixed, "0.0001729"},
265     {1.729e-3f, chars_format::fixed, "0.001729"},
266     {1.729e-2f, chars_format::fixed, "0.01729"},
267     {1.729e-1f, chars_format::fixed, "0.1729"},
268     {1.729e0f, chars_format::fixed, "1.729"},
269     {1.729e1f, chars_format::fixed, "17.29"},
270     {1.729e2f, chars_format::fixed, "172.9"},
271     {1.729e3f, chars_format::fixed, "1729"},
272     {1.729e4f, chars_format::fixed, "17290"},
273     {1.729e5f, chars_format::fixed, "172900"},
274     {1.729e6f, chars_format::fixed, "1729000"},
275     {1.729e7f, chars_format::fixed, "17290000"},
276     {1.729e8f, chars_format::fixed, "172900000"},
277     {1.729e9f, chars_format::fixed, "1728999936"},
278     {1.729e10f, chars_format::fixed, "17290000384"},
279     {1.729e11f, chars_format::fixed, "172900007936"},
280     {1.729e12f, chars_format::fixed, "1728999981056"},
281     {1.729e13f, chars_format::fixed, "17290000072704"},
282     {1.729e14f, chars_format::fixed, "172899998629888"},
283     {1.729e15f, chars_format::fixed, "1729000019853312"},
284     {1.729e16f, chars_format::fixed, "17289999661662208"},
285     {1.729e17f, chars_format::fixed, "172900007354040320"},
286     {1.729e18f, chars_format::fixed, "1729000039180664832"},
287     {1.729e19f, chars_format::fixed, "17289999567172927488"},
288     {1.729e20f, chars_format::fixed, "172899997870752530432"},
289     {1.729e21f, chars_format::fixed, "1729000013891897393152"},
290     {1.729e22f, chars_format::fixed, "17290000138918973931520"},
291     {1.729e23f, chars_format::fixed, "172899999137389925629952"},
292     {1.729e24f, chars_format::fixed, "1729000063431493294227456"},
293     {1.729e25f, chars_format::fixed, "17289999481393428335427584"},
294     {1.729e26f, chars_format::fixed, "172900004037306320209051648"},
295     {1.729e27f, chars_format::fixed, "1729000040373063202090516480"},
296     {1.729e28f, chars_format::fixed, "17290000403730632020905164800"},
297     {1.729e29f, chars_format::fixed, "172900004037306320209051648000"},
298     {1.729e30f, chars_format::fixed, "1728999964815199476176193060864"},
299     {1.729e31f, chars_format::fixed, "17290000252614904569076517961728"},
300     {1.729e32f, chars_format::fixed, "172899990436890849544473432555520"},
301     {1.729e33f, chars_format::fixed, "1729000059111413406117268687945728"},
302     {1.729e34f, chars_format::fixed, "17290000281629124239827618154676224"},
303     {1.729e35f, chars_format::fixed, "172899995388651006685994532152016896"},
304     {1.729e36f, chars_format::fixed, "1728999993500591323992114118292144128"},
305     {1.729e37f, chars_format::fixed, "17289999935005913239921141182921441280"},
306     {1.729e38f, chars_format::fixed, "172899996814757931942752608835808002048"},
307 
308     // Also test one-digit cases, where the decimal point can't appear between digits like "17.29".
309     {7e-3f, chars_format::fixed, "0.007"},
310     {7e-2f, chars_format::fixed, "0.07"},
311     {7e-1f, chars_format::fixed, "0.7"},
312     {7e0f, chars_format::fixed, "7"},
313     {7e1f, chars_format::fixed, "70"},
314     {7e2f, chars_format::fixed, "700"},
315     {7e3f, chars_format::fixed, "7000"},
316 
317     // Test the maximum value in fixed notation.
318     {0x1.fffffep+127f, chars_format::fixed, "340282346638528859811704183484516925440"},
319 
320     // Test highly-trimmed powers of 2.
321     {0x1p118f, chars_format::fixed, "332306998946228968225951765070086144"},
322     {0x1p118f, chars_format::scientific, "3.32307e+35"},
323     {0x1p119f, chars_format::fixed, "664613997892457936451903530140172288"},
324     {0x1p119f, chars_format::scientific, "6.64614e+35"},
325 
326     // Test powers of 10 that are exactly representable.
327     {1e0f, chars_format::fixed, "1"},
328     {1e1f, chars_format::fixed, "10"},
329     {1e2f, chars_format::fixed, "100"},
330     {1e3f, chars_format::fixed, "1000"},
331     {1e4f, chars_format::fixed, "10000"},
332     {1e5f, chars_format::fixed, "100000"},
333     {1e6f, chars_format::fixed, "1000000"},
334     {1e7f, chars_format::fixed, "10000000"},
335     {1e8f, chars_format::fixed, "100000000"},
336     {1e9f, chars_format::fixed, "1000000000"},
337     {1e10f, chars_format::fixed, "10000000000"},
338 
339     // Test powers of 10 that aren't exactly representable.
340     // This exercises the "adjustment" code.
341     {1e11f, chars_format::fixed, "99999997952"},
342     {1e12f, chars_format::fixed, "999999995904"},
343     {1e13f, chars_format::fixed, "9999999827968"},
344     {1e14f, chars_format::fixed, "100000000376832"},
345     {1e15f, chars_format::fixed, "999999986991104"},
346     {1e16f, chars_format::fixed, "10000000272564224"},
347     {1e17f, chars_format::fixed, "99999998430674944"},
348     {1e18f, chars_format::fixed, "999999984306749440"},
349     {1e19f, chars_format::fixed, "9999999980506447872"},
350     {1e20f, chars_format::fixed, "100000002004087734272"},
351     {1e21f, chars_format::fixed, "1000000020040877342720"},
352     {1e22f, chars_format::fixed, "9999999778196308361216"},
353     {1e23f, chars_format::fixed, "99999997781963083612160"},
354     {1e24f, chars_format::fixed, "1000000013848427855085568"},
355     {1e25f, chars_format::fixed, "9999999562023526247432192"},
356     {1e26f, chars_format::fixed, "100000002537764290115403776"},
357     {1e27f, chars_format::fixed, "999999988484154753734934528"},
358     {1e28f, chars_format::fixed, "9999999442119689768320106496"},
359     {1e29f, chars_format::fixed, "100000001504746621987668885504"},
360     {1e30f, chars_format::fixed, "1000000015047466219876688855040"},
361     {1e31f, chars_format::fixed, "9999999848243207295109594873856"},
362     {1e32f, chars_format::fixed, "100000003318135351409612647563264"},
363     {1e33f, chars_format::fixed, "999999994495727286427992885035008"},
364     {1e34f, chars_format::fixed, "9999999790214767953607394487959552"},
365     {1e35f, chars_format::fixed, "100000004091847875962975319375216640"},
366     {1e36f, chars_format::fixed, "999999961690316245365415600208216064"},
367     {1e37f, chars_format::fixed, "9999999933815812510711506376257961984"},
368     {1e38f, chars_format::fixed, "99999996802856924650656260769173209088"},
369 
370     // These numbers have odd mantissas (unaffected by shifting)
371     // that are barely within the "max shifted mantissa" limit.
372     // They're exactly-representable multiples of powers of 10, and can use Ryu with zero-filling.
373     {3355443e1f, chars_format::fixed, "33554430"},
374     {671087e2f, chars_format::fixed, "67108700"},
375     {134217e3f, chars_format::fixed, "134217000"},
376     {26843e4f, chars_format::fixed, "268430000"},
377     {5367e5f, chars_format::fixed, "536700000"},
378     {1073e6f, chars_format::fixed, "1073000000"},
379     {213e7f, chars_format::fixed, "2130000000"},
380     {41e8f, chars_format::fixed, "4100000000"},
381     {7e9f, chars_format::fixed, "7000000000"},
382     {1e10f, chars_format::fixed, "10000000000"},
383 
384     // These numbers have odd mantissas (unaffected by shifting)
385     // that are barely above the "max shifted mantissa" limit.
386     // This activates the non-Ryu fallback for large integers.
387     {3355445e1f, chars_format::fixed, "33554448"},
388     {671089e2f, chars_format::fixed, "67108896"},
389     {134219e3f, chars_format::fixed, "134219008"},
390     {26845e4f, chars_format::fixed, "268449984"},
391     {5369e5f, chars_format::fixed, "536899968"},
392     {1075e6f, chars_format::fixed, "1075000064"},
393     {215e7f, chars_format::fixed, "2150000128"},
394     {43e8f, chars_format::fixed, "4300000256"},
395     {9e9f, chars_format::fixed, "8999999488"},
396     {3e10f, chars_format::fixed, "30000001024"},
397 
398     // Test the mantissa shifting logic.
399     {5495808e5f, chars_format::fixed, "549580800000"}, // 5367 * 2^10
400     {5497856e5f, chars_format::fixed, "549785567232"}, // 5369 * 2^10
401 
402     // Inspect all of those numbers in scientific notation.
403     // For the within-limit numbers, this verifies that Ryu is actually being used with zero-filling above.
404     // For the above-limit numbers, this tests Ryu's trimming.
405     {3355443e1f, chars_format::scientific, "3.355443e+07"},
406     {671087e2f, chars_format::scientific, "6.71087e+07"},
407     {134217e3f, chars_format::scientific, "1.34217e+08"},
408     {26843e4f, chars_format::scientific, "2.6843e+08"},
409     {5367e5f, chars_format::scientific, "5.367e+08"},
410     {1073e6f, chars_format::scientific, "1.073e+09"},
411     {213e7f, chars_format::scientific, "2.13e+09"},
412     {41e8f, chars_format::scientific, "4.1e+09"},
413     {7e9f, chars_format::scientific, "7e+09"},
414     {1e10f, chars_format::scientific, "1e+10"},
415     {3355445e1f, chars_format::scientific, "3.355445e+07"},
416     {671089e2f, chars_format::scientific, "6.71089e+07"},
417     {134219e3f, chars_format::scientific, "1.34219e+08"},
418     {26845e4f, chars_format::scientific, "2.6845e+08"},
419     {5369e5f, chars_format::scientific, "5.369e+08"},
420     {1075e6f, chars_format::scientific, "1.075e+09"},
421     {215e7f, chars_format::scientific, "2.15e+09"},
422     {43e8f, chars_format::scientific, "4.3e+09"},
423     {9e9f, chars_format::scientific, "9e+09"},
424     {3e10f, chars_format::scientific, "3e+10"},
425     {5495808e5f, chars_format::scientific, "5.495808e+11"},
426     {5497856e5f, chars_format::scientific, "5.497856e+11"},
427 
428     // Test the switching logic of chars_format::general.
429     // C11 7.21.6.1 "The fprintf function"/8:
430     // "Let P equal [...] 6 if the precision is omitted [...].
431     // Then, if a conversion with style E would have an exponent of X:
432     // - if P > X >= -4, the conversion is with style f [...].
433     // - otherwise, the conversion is with style e [...]."
434     {1e-6f, chars_format::general, "1e-06"},
435     {1e-5f, chars_format::general, "1e-05"},
436     {1e-4f, chars_format::general, "0.0001"},
437     {1e-3f, chars_format::general, "0.001"},
438     {1e-2f, chars_format::general, "0.01"},
439     {1e-1f, chars_format::general, "0.1"},
440     {1e0f, chars_format::general, "1"},
441     {1e1f, chars_format::general, "10"},
442     {1e2f, chars_format::general, "100"},
443     {1e3f, chars_format::general, "1000"},
444     {1e4f, chars_format::general, "10000"},
445     {1e5f, chars_format::general, "100000"},
446     {1e6f, chars_format::general, "1e+06"},
447     {1e7f, chars_format::general, "1e+07"},
448     {1.234e-6f, chars_format::general, "1.234e-06"},
449     {1.234e-5f, chars_format::general, "1.234e-05"},
450     {1.234e-4f, chars_format::general, "0.0001234"},
451     {1.234e-3f, chars_format::general, "0.001234"},
452     {1.234e-2f, chars_format::general, "0.01234"},
453     {1.234e-1f, chars_format::general, "0.1234"},
454     {1.234e0f, chars_format::general, "1.234"},
455     {1.234e1f, chars_format::general, "12.34"},
456     {1.234e2f, chars_format::general, "123.4"},
457     {1.234e3f, chars_format::general, "1234"},
458     {1.234e4f, chars_format::general, "12340"},
459     {1.234e5f, chars_format::general, "123400"},
460     {1.234e6f, chars_format::general, "1.234e+06"},
461     {1.234e7f, chars_format::general, "1.234e+07"},
462     {1.234e8f, chars_format::general, "1.234e+08"},
463     {1.234e9f, chars_format::general, "1.234e+09"},
464     {1.234e10f, chars_format::general, "1.234e+10"},
465 
466     // Test the switching logic of the plain overload.
467     // N4762 19.19.2 [charconv.to.chars]/8:
468     // "The conversion specifier is f or e, chosen according to the requirement
469     // for a shortest representation (see above); a tie is resolved in favor of f."
470     {1e-6f, chars_format{}, "1e-06"},
471     {1e-5f, chars_format{}, "1e-05"},
472     {1e-4f, chars_format{}, "1e-04"},
473     {1e-3f, chars_format{}, "0.001"},
474     {1e-2f, chars_format{}, "0.01"},
475     {1e-1f, chars_format{}, "0.1"},
476     {1e0f, chars_format{}, "1"},
477     {1e1f, chars_format{}, "10"},
478     {1e2f, chars_format{}, "100"},
479     {1e3f, chars_format{}, "1000"},
480     {1e4f, chars_format{}, "10000"},
481     {1e5f, chars_format{}, "1e+05"},
482     {1e6f, chars_format{}, "1e+06"},
483     {1e7f, chars_format{}, "1e+07"},
484     {1.234e-6f, chars_format{}, "1.234e-06"},
485     {1.234e-5f, chars_format{}, "1.234e-05"},
486     {1.234e-4f, chars_format{}, "0.0001234"},
487     {1.234e-3f, chars_format{}, "0.001234"},
488     {1.234e-2f, chars_format{}, "0.01234"},
489     {1.234e-1f, chars_format{}, "0.1234"},
490     {1.234e0f, chars_format{}, "1.234"},
491     {1.234e1f, chars_format{}, "12.34"},
492     {1.234e2f, chars_format{}, "123.4"},
493     {1.234e3f, chars_format{}, "1234"},
494     {1.234e4f, chars_format{}, "12340"},
495     {1.234e5f, chars_format{}, "123400"},
496     {1.234e6f, chars_format{}, "1234000"},
497     {1.234e7f, chars_format{}, "12340000"},
498     {1.234e8f, chars_format{}, "123400000"},
499     {1.234e9f, chars_format{}, "1.234e+09"},
500     {1.234e10f, chars_format{}, "1.234e+10"},
501 
502     // Test hexfloat corner cases.
503     {0x1.728p+0f, chars_format::hex, "1.728p+0"}, // instead of "2.e5p-1"
504     {0x0.000002p-126f, chars_format::hex, "0.000002p-126"}, // instead of "1p-149", min subnormal
505     {0x0.fffffep-126f, chars_format::hex, "0.fffffep-126"}, // max subnormal
506     {0x1p-126f, chars_format::hex, "1p-126"}, // min normal
507     {0x1.fffffep+127f, chars_format::hex, "1.fffffep+127"}, // max normal
508 
509     // Test hexfloat exponents.
510     {0x1p-109f, chars_format::hex, "1p-109"},
511     {0x1p-99f, chars_format::hex, "1p-99"},
512     {0x1p-9f, chars_format::hex, "1p-9"},
513     {0x1p+0f, chars_format::hex, "1p+0"},
514     {0x1p+9f, chars_format::hex, "1p+9"},
515     {0x1p+99f, chars_format::hex, "1p+99"},
516     {0x1p+109f, chars_format::hex, "1p+109"},
517 
518     // Test hexfloat hexits.
519     {0x1.0123p+0f, chars_format::hex, "1.0123p+0"},
520     {0x1.4567p+0f, chars_format::hex, "1.4567p+0"},
521     {0x1.89abp+0f, chars_format::hex, "1.89abp+0"},
522     {0x1.cdefp+0f, chars_format::hex, "1.cdefp+0"},
523 
524     // Test hexfloat trimming.
525     {0x1.00000ap+0f, chars_format::hex, "1.00000ap+0"},
526     {0x1.0000ap+0f, chars_format::hex, "1.0000ap+0"},
527     {0x1.000ap+0f, chars_format::hex, "1.000ap+0"},
528     {0x1.00ap+0f, chars_format::hex, "1.00ap+0"},
529     {0x1.0ap+0f, chars_format::hex, "1.0ap+0"},
530     {0x1.ap+0f, chars_format::hex, "1.ap+0"},
531     {0x1p+0f, chars_format::hex, "1p+0"},
532 
533     // https://www.exploringbinary.com/the-shortest-decimal-string-that-round-trips-may-not-be-the-nearest/
534     // This is an exhaustive list of anomalous values.
535     // (See double_to_chars_test_cases.hpp for more details.)
536     {0x1p90f, chars_format::scientific, "1.2379401e+27"},
537     {0x1p87f, chars_format::scientific, "1.5474251e+26"},
538     {0x1p-96f, chars_format::scientific, "1.2621775e-29"},
539 };
540 
541 #endif // FLOAT_TO_CHARS_TEST_CASES_HPP
542