1 use std::mem::MaybeUninit;
2 use std::{fmt, str};
3 
4 use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
5 use core::num::flt2dec::{round_up, Sign, MAX_SIG_DIGITS};
6 use core::num::flt2dec::{
7     to_exact_exp_str, to_exact_fixed_str, to_shortest_exp_str, to_shortest_str,
8 };
9 use core::num::fmt::{Formatted, Part};
10 
11 pub use test::Bencher;
12 
13 mod estimator;
14 mod strategy {
15     mod dragon;
16     mod grisu;
17 }
18 mod random;
19 
decode_finite<T: DecodableFloat>(v: T) -> Decoded20 pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
21     match decode(v).1 {
22         FullDecoded::Finite(decoded) => decoded,
23         full_decoded => panic!("expected finite, got {:?} instead", full_decoded),
24     }
25 }
26 
27 macro_rules! check_shortest {
28     ($f:ident($v:expr) => $buf:expr, $exp:expr) => (
29         check_shortest!($f($v) => $buf, $exp;
30                         "shortest mismatch for v={v}: actual {actual:?}, expected {expected:?}",
31                         v = stringify!($v))
32     );
33 
34     ($f:ident{$($k:ident: $v:expr),+} => $buf:expr, $exp:expr) => (
35         check_shortest!($f{$($k: $v),+} => $buf, $exp;
36                         "shortest mismatch for {v:?}: actual {actual:?}, expected {expected:?}",
37                         v = Decoded { $($k: $v),+ })
38     );
39 
40     ($f:ident($v:expr) => $buf:expr, $exp:expr; $fmt:expr, $($key:ident = $val:expr),*) => ({
41         let mut buf = [MaybeUninit::new(b'_'); MAX_SIG_DIGITS];
42         let (buf, k) = $f(&decode_finite($v), &mut buf);
43         assert!((buf, k) == ($buf, $exp),
44                 $fmt, actual = (str::from_utf8(buf).unwrap(), k),
45                       expected = (str::from_utf8($buf).unwrap(), $exp),
46                       $($key = $val),*);
47     });
48 
49     ($f:ident{$($k:ident: $v:expr),+} => $buf:expr, $exp:expr;
50                                          $fmt:expr, $($key:ident = $val:expr),*) => ({
51         let mut buf = [MaybeUninit::new(b'_'); MAX_SIG_DIGITS];
52         let (buf, k) = $f(&Decoded { $($k: $v),+ }, &mut buf);
53         assert!((buf, k) == ($buf, $exp),
54                 $fmt, actual = (str::from_utf8(buf).unwrap(), k),
55                       expected = (str::from_utf8($buf).unwrap(), $exp),
56                       $($key = $val),*);
57     })
58 }
59 
60 macro_rules! try_exact {
61     ($f:ident($decoded:expr) => $buf:expr, $expected:expr, $expectedk:expr;
62                                 $fmt:expr, $($key:ident = $val:expr),*) => ({
63         let (buf, k) = $f($decoded, &mut $buf[..$expected.len()], i16::MIN);
64         assert!((buf, k) == ($expected, $expectedk),
65                 $fmt, actual = (str::from_utf8(buf).unwrap(), k),
66                       expected = (str::from_utf8($expected).unwrap(), $expectedk),
67                       $($key = $val),*);
68     })
69 }
70 
71 macro_rules! try_fixed {
72     ($f:ident($decoded:expr) => $buf:expr, $request:expr, $expected:expr, $expectedk:expr;
73                                 $fmt:expr, $($key:ident = $val:expr),*) => ({
74         let (buf, k) = $f($decoded, &mut $buf[..], $request);
75         assert!((buf, k) == ($expected, $expectedk),
76                 $fmt, actual = (str::from_utf8(buf).unwrap(), k),
77                       expected = (str::from_utf8($expected).unwrap(), $expectedk),
78                       $($key = $val),*);
79     })
80 }
81 
ldexp_f32(a: f32, b: i32) -> f3282 fn ldexp_f32(a: f32, b: i32) -> f32 {
83     ldexp_f64(a as f64, b) as f32
84 }
85 
ldexp_f64(a: f64, b: i32) -> f6486 fn ldexp_f64(a: f64, b: i32) -> f64 {
87     extern "C" {
88         fn ldexp(x: f64, n: i32) -> f64;
89     }
90     // SAFETY: assuming a correct `ldexp` has been supplied, the given arguments cannot possibly
91     // cause undefined behavior
92     unsafe { ldexp(a, b) }
93 }
94 
check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16) where T: DecodableFloat, F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),95 fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16)
96 where
97     T: DecodableFloat,
98     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
99 {
100     // use a large enough buffer
101     let mut buf = [MaybeUninit::new(b'_'); 1024];
102     let mut expected_ = [b'_'; 1024];
103 
104     let decoded = decode_finite(v);
105     let cut = expected.iter().position(|&c| c == b' ');
106 
107     // check significant digits
108     for i in 1..cut.unwrap_or(expected.len() - 1) {
109         expected_[..i].copy_from_slice(&expected[..i]);
110         let mut expectedk_ = expectedk;
111         if expected[i] >= b'5' {
112             // check if this is a rounding-to-even case.
113             // we avoid rounding ...x5000... (with infinite zeroes) to ...(x+1) when x is even.
114             if !(i + 1 < expected.len()
115                 && expected[i - 1] & 1 == 0
116                 && expected[i] == b'5'
117                 && expected[i + 1] == b' ')
118             {
119                 // if this returns true, expected_[..i] is all `9`s and being rounded up.
120                 // we should always return `100..00` (`i` digits) instead, since that's
121                 // what we can came up with `i` digits anyway. `round_up` assumes that
122                 // the adjustment to the length is done by caller, which we simply ignore.
123                 if let Some(_) = round_up(&mut expected_[..i]) {
124                     expectedk_ += 1;
125                 }
126             }
127         }
128 
129         try_exact!(f(&decoded) => &mut buf, &expected_[..i], expectedk_;
130                    "exact sigdigit mismatch for v={v}, i={i}: \
131                     actual {actual:?}, expected {expected:?}",
132                    v = vstr, i = i);
133         try_fixed!(f(&decoded) => &mut buf, expectedk_ - i as i16, &expected_[..i], expectedk_;
134                    "fixed sigdigit mismatch for v={v}, i={i}: \
135                     actual {actual:?}, expected {expected:?}",
136                    v = vstr, i = i);
137     }
138 
139     // check exact rounding for zero- and negative-width cases
140     let start;
141     if expected[0] >= b'5' {
142         try_fixed!(f(&decoded) => &mut buf, expectedk, b"1", expectedk + 1;
143                    "zero-width rounding-up mismatch for v={v}: \
144                     actual {actual:?}, expected {expected:?}",
145                    v = vstr);
146         start = 1;
147     } else {
148         start = 0;
149     }
150     for i in start..-10 {
151         try_fixed!(f(&decoded) => &mut buf, expectedk - i, b"", expectedk;
152                    "rounding-down mismatch for v={v}, i={i}: \
153                     actual {actual:?}, expected {expected:?}",
154                    v = vstr, i = -i);
155     }
156 
157     // check infinite zero digits
158     if let Some(cut) = cut {
159         for i in cut..expected.len() - 1 {
160             expected_[..cut].copy_from_slice(&expected[..cut]);
161             for c in &mut expected_[cut..i] {
162                 *c = b'0';
163             }
164 
165             try_exact!(f(&decoded) => &mut buf, &expected_[..i], expectedk;
166                        "exact infzero mismatch for v={v}, i={i}: \
167                         actual {actual:?}, expected {expected:?}",
168                        v = vstr, i = i);
169             try_fixed!(f(&decoded) => &mut buf, expectedk - i as i16, &expected_[..i], expectedk;
170                        "fixed infzero mismatch for v={v}, i={i}: \
171                         actual {actual:?}, expected {expected:?}",
172                        v = vstr, i = i);
173         }
174     }
175 }
176 
177 trait TestableFloat: DecodableFloat + fmt::Display {
178     /// Returns `x * 2^exp`. Almost same to `std::{f32,f64}::ldexp`.
179     /// This is used for testing.
ldexpi(f: i64, exp: isize) -> Self180     fn ldexpi(f: i64, exp: isize) -> Self;
181 }
182 
183 impl TestableFloat for f32 {
ldexpi(f: i64, exp: isize) -> Self184     fn ldexpi(f: i64, exp: isize) -> Self {
185         f as Self * (exp as Self).exp2()
186     }
187 }
188 
189 impl TestableFloat for f64 {
ldexpi(f: i64, exp: isize) -> Self190     fn ldexpi(f: i64, exp: isize) -> Self {
191         f as Self * (exp as Self).exp2()
192     }
193 }
194 
check_exact_one<F, T>(mut f: F, x: i64, e: isize, tstr: &str, expected: &[u8], expectedk: i16) where T: TestableFloat, F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),195 fn check_exact_one<F, T>(mut f: F, x: i64, e: isize, tstr: &str, expected: &[u8], expectedk: i16)
196 where
197     T: TestableFloat,
198     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
199 {
200     // use a large enough buffer
201     let mut buf = [MaybeUninit::new(b'_'); 1024];
202     let v: T = TestableFloat::ldexpi(x, e);
203     let decoded = decode_finite(v);
204 
205     try_exact!(f(&decoded) => &mut buf, &expected, expectedk;
206                "exact mismatch for v={x}p{e}{t}: actual {actual:?}, expected {expected:?}",
207                x = x, e = e, t = tstr);
208     try_fixed!(f(&decoded) => &mut buf, expectedk - expected.len() as i16, &expected, expectedk;
209                "fixed mismatch for v={x}p{e}{t}: actual {actual:?}, expected {expected:?}",
210                x = x, e = e, t = tstr);
211 }
212 
213 macro_rules! check_exact {
214     ($f:ident($v:expr) => $buf:expr, $exp:expr) => {
215         check_exact(|d, b, k| $f(d, b, k), $v, stringify!($v), $buf, $exp)
216     };
217 }
218 
219 macro_rules! check_exact_one {
220     ($f:ident($x:expr, $e:expr; $t:ty) => $buf:expr, $exp:expr) => {
221         check_exact_one::<_, $t>(|d, b, k| $f(d, b, k), $x, $e, stringify!($t), $buf, $exp)
222     };
223 }
224 
225 // in the following comments, three numbers are spaced by 1 ulp apart,
226 // and the second one is being formatted.
227 //
228 // some tests are derived from [1].
229 //
230 // [1] Vern Paxson, A Program for Testing IEEE Decimal-Binary Conversion
231 //     ftp://ftp.ee.lbl.gov/testbase-report.ps.Z
232 
f32_shortest_sanity_test<F>(mut f: F) where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),233 pub fn f32_shortest_sanity_test<F>(mut f: F)
234 where
235     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
236 {
237     // 0.0999999940395355224609375
238     // 0.100000001490116119384765625
239     // 0.10000000894069671630859375
240     check_shortest!(f(0.1f32) => b"1", 0);
241 
242     // 0.333333313465118408203125
243     // 0.3333333432674407958984375 (1/3 in the default rounding)
244     // 0.33333337306976318359375
245     check_shortest!(f(1.0f32/3.0) => b"33333334", 0);
246 
247     // 10^1 * 0.31415917873382568359375
248     // 10^1 * 0.31415920257568359375
249     // 10^1 * 0.31415922641754150390625
250     check_shortest!(f(3.141592f32) => b"3141592", 1);
251 
252     // 10^18 * 0.31415916243714048
253     // 10^18 * 0.314159196796878848
254     // 10^18 * 0.314159231156617216
255     check_shortest!(f(3.141592e17f32) => b"3141592", 18);
256 
257     // regression test for decoders
258     // 10^8 * 0.3355443
259     // 10^8 * 0.33554432
260     // 10^8 * 0.33554436
261     check_shortest!(f(ldexp_f32(1.0, 25)) => b"33554432", 8);
262 
263     // 10^39 * 0.340282326356119256160033759537265639424
264     // 10^39 * 0.34028234663852885981170418348451692544
265     // 10^39 * 0.340282366920938463463374607431768211456
266     check_shortest!(f(f32::MAX) => b"34028235", 39);
267 
268     // 10^-37 * 0.1175494210692441075487029444849287348827...
269     // 10^-37 * 0.1175494350822287507968736537222245677818...
270     // 10^-37 * 0.1175494490952133940450443629595204006810...
271     check_shortest!(f(f32::MIN_POSITIVE) => b"11754944", -37);
272 
273     // 10^-44 * 0
274     // 10^-44 * 0.1401298464324817070923729583289916131280...
275     // 10^-44 * 0.2802596928649634141847459166579832262560...
276     let minf32 = ldexp_f32(1.0, -149);
277     check_shortest!(f(minf32) => b"1", -44);
278 }
279 
f32_exact_sanity_test<F>(mut f: F) where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),280 pub fn f32_exact_sanity_test<F>(mut f: F)
281 where
282     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
283 {
284     let minf32 = ldexp_f32(1.0, -149);
285 
286     check_exact!(f(0.1f32)            => b"100000001490116119384765625             ", 0);
287     check_exact!(f(0.5f32)            => b"5                                       ", 0);
288     check_exact!(f(1.0f32/3.0)        => b"3333333432674407958984375               ", 0);
289     check_exact!(f(3.141592f32)       => b"31415920257568359375                    ", 1);
290     check_exact!(f(3.141592e17f32)    => b"314159196796878848                      ", 18);
291     check_exact!(f(f32::MAX)          => b"34028234663852885981170418348451692544  ", 39);
292     check_exact!(f(f32::MIN_POSITIVE) => b"1175494350822287507968736537222245677818", -37);
293     check_exact!(f(minf32)            => b"1401298464324817070923729583289916131280", -44);
294 
295     // [1], Table 16: Stress Inputs for Converting 24-bit Binary to Decimal, < 1/2 ULP
296     check_exact_one!(f(12676506, -102; f32) => b"2",            -23);
297     check_exact_one!(f(12676506, -103; f32) => b"12",           -23);
298     check_exact_one!(f(15445013,   86; f32) => b"119",           34);
299     check_exact_one!(f(13734123, -138; f32) => b"3941",         -34);
300     check_exact_one!(f(12428269, -130; f32) => b"91308",        -32);
301     check_exact_one!(f(15334037, -146; f32) => b"171900",       -36);
302     check_exact_one!(f(11518287,  -41; f32) => b"5237910",       -5);
303     check_exact_one!(f(12584953, -145; f32) => b"28216440",     -36);
304     check_exact_one!(f(15961084, -125; f32) => b"375243281",    -30);
305     check_exact_one!(f(14915817, -146; f32) => b"1672120916",   -36);
306     check_exact_one!(f(10845484, -102; f32) => b"21388945814",  -23);
307     check_exact_one!(f(16431059,  -61; f32) => b"712583594561", -11);
308 
309     // [1], Table 17: Stress Inputs for Converting 24-bit Binary to Decimal, > 1/2 ULP
310     check_exact_one!(f(16093626,   69; f32) => b"1",             29);
311     check_exact_one!(f( 9983778,   25; f32) => b"34",            15);
312     check_exact_one!(f(12745034,  104; f32) => b"259",           39);
313     check_exact_one!(f(12706553,   72; f32) => b"6001",          29);
314     check_exact_one!(f(11005028,   45; f32) => b"38721",         21);
315     check_exact_one!(f(15059547,   71; f32) => b"355584",        29);
316     check_exact_one!(f(16015691,  -99; f32) => b"2526831",      -22);
317     check_exact_one!(f( 8667859,   56; f32) => b"62458507",      24);
318     check_exact_one!(f(14855922,  -82; f32) => b"307213267",    -17);
319     check_exact_one!(f(14855922,  -83; f32) => b"1536066333",   -17);
320     check_exact_one!(f(10144164, -110; f32) => b"78147796834",  -26);
321     check_exact_one!(f(13248074,   95; f32) => b"524810279937",  36);
322 }
323 
f64_shortest_sanity_test<F>(mut f: F) where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),324 pub fn f64_shortest_sanity_test<F>(mut f: F)
325 where
326     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
327 {
328     // 0.0999999999999999777955395074968691915273...
329     // 0.1000000000000000055511151231257827021181...
330     // 0.1000000000000000333066907387546962127089...
331     check_shortest!(f(0.1f64) => b"1", 0);
332 
333     // this example is explicitly mentioned in the paper.
334     // 10^3 * 0.0999999999999999857891452847979962825775...
335     // 10^3 * 0.1 (exact)
336     // 10^3 * 0.1000000000000000142108547152020037174224...
337     check_shortest!(f(100.0f64) => b"1", 3);
338 
339     // 0.3333333333333332593184650249895639717578...
340     // 0.3333333333333333148296162562473909929394... (1/3 in the default rounding)
341     // 0.3333333333333333703407674875052180141210...
342     check_shortest!(f(1.0f64/3.0) => b"3333333333333333", 0);
343 
344     // explicit test case for equally closest representations.
345     // Dragon has its own tie-breaking rule; Grisu should fall back.
346     // 10^1 * 0.1000007629394531027955395074968691915273...
347     // 10^1 * 0.100000762939453125 (exact)
348     // 10^1 * 0.1000007629394531472044604925031308084726...
349     check_shortest!(f(1.00000762939453125f64) => b"10000076293945313", 1);
350 
351     // 10^1 * 0.3141591999999999718085064159822650253772...
352     // 10^1 * 0.3141592000000000162174274009885266423225...
353     // 10^1 * 0.3141592000000000606263483859947882592678...
354     check_shortest!(f(3.141592f64) => b"3141592", 1);
355 
356     // 10^18 * 0.314159199999999936
357     // 10^18 * 0.3141592 (exact)
358     // 10^18 * 0.314159200000000064
359     check_shortest!(f(3.141592e17f64) => b"3141592", 18);
360 
361     // regression test for decoders
362     // 10^20 * 0.18446744073709549568
363     // 10^20 * 0.18446744073709551616
364     // 10^20 * 0.18446744073709555712
365     check_shortest!(f(ldexp_f64(1.0, 64)) => b"18446744073709552", 20);
366 
367     // pathological case: high = 10^23 (exact). tie breaking should always prefer that.
368     // 10^24 * 0.099999999999999974834176
369     // 10^24 * 0.099999999999999991611392
370     // 10^24 * 0.100000000000000008388608
371     check_shortest!(f(1.0e23f64) => b"1", 24);
372 
373     // 10^309 * 0.1797693134862315508561243283845062402343...
374     // 10^309 * 0.1797693134862315708145274237317043567980...
375     // 10^309 * 0.1797693134862315907729305190789024733617...
376     check_shortest!(f(f64::MAX) => b"17976931348623157", 309);
377 
378     // 10^-307 * 0.2225073858507200889024586876085859887650...
379     // 10^-307 * 0.2225073858507201383090232717332404064219...
380     // 10^-307 * 0.2225073858507201877155878558578948240788...
381     check_shortest!(f(f64::MIN_POSITIVE) => b"22250738585072014", -307);
382 
383     // 10^-323 * 0
384     // 10^-323 * 0.4940656458412465441765687928682213723650...
385     // 10^-323 * 0.9881312916824930883531375857364427447301...
386     let minf64 = ldexp_f64(1.0, -1074);
387     check_shortest!(f(minf64) => b"5", -323);
388 }
389 
f64_exact_sanity_test<F>(mut f: F) where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),390 pub fn f64_exact_sanity_test<F>(mut f: F)
391 where
392     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
393 {
394     let minf64 = ldexp_f64(1.0, -1074);
395 
396     check_exact!(f(0.1f64)            => b"1000000000000000055511151231257827021181", 0);
397     check_exact!(f(0.45f64)           => b"4500000000000000111022302462515654042363", 0);
398     check_exact!(f(0.5f64)            => b"5                                       ", 0);
399     check_exact!(f(0.95f64)           => b"9499999999999999555910790149937383830547", 0);
400     check_exact!(f(100.0f64)          => b"1                                       ", 3);
401     check_exact!(f(999.5f64)          => b"9995000000000000000000000000000000000000", 3);
402     check_exact!(f(1.0f64/3.0)        => b"3333333333333333148296162562473909929394", 0);
403     check_exact!(f(3.141592f64)       => b"3141592000000000162174274009885266423225", 1);
404     check_exact!(f(3.141592e17f64)    => b"3141592                                 ", 18);
405     check_exact!(f(1.0e23f64)         => b"99999999999999991611392                 ", 23);
406     check_exact!(f(f64::MAX)          => b"1797693134862315708145274237317043567980", 309);
407     check_exact!(f(f64::MIN_POSITIVE) => b"2225073858507201383090232717332404064219", -307);
408     check_exact!(f(minf64)            => b"4940656458412465441765687928682213723650\
409                                            5980261432476442558568250067550727020875\
410                                            1865299836361635992379796564695445717730\
411                                            9266567103559397963987747960107818781263\
412                                            0071319031140452784581716784898210368871\
413                                            8636056998730723050006387409153564984387\
414                                            3124733972731696151400317153853980741262\
415                                            3856559117102665855668676818703956031062\
416                                            4931945271591492455329305456544401127480\
417                                            1297099995419319894090804165633245247571\
418                                            4786901472678015935523861155013480352649\
419                                            3472019379026810710749170333222684475333\
420                                            5720832431936092382893458368060106011506\
421                                            1698097530783422773183292479049825247307\
422                                            7637592724787465608477820373446969953364\
423                                            7017972677717585125660551199131504891101\
424                                            4510378627381672509558373897335989936648\
425                                            0994116420570263709027924276754456522908\
426                                            7538682506419718265533447265625         ", -323);
427 
428     // [1], Table 3: Stress Inputs for Converting 53-bit Binary to Decimal, < 1/2 ULP
429     check_exact_one!(f(8511030020275656,  -342; f64) => b"9",                       -87);
430     check_exact_one!(f(5201988407066741,  -824; f64) => b"46",                     -232);
431     check_exact_one!(f(6406892948269899,   237; f64) => b"141",                      88);
432     check_exact_one!(f(8431154198732492,    72; f64) => b"3981",                     38);
433     check_exact_one!(f(6475049196144587,    99; f64) => b"41040",                    46);
434     check_exact_one!(f(8274307542972842,   726; f64) => b"292084",                  235);
435     check_exact_one!(f(5381065484265332,  -456; f64) => b"2891946",                -121);
436     check_exact_one!(f(6761728585499734, -1057; f64) => b"43787718",               -302);
437     check_exact_one!(f(7976538478610756,   376; f64) => b"122770163",               130);
438     check_exact_one!(f(5982403858958067,   377; f64) => b"1841552452",              130);
439     check_exact_one!(f(5536995190630837,    93; f64) => b"54835744350",              44);
440     check_exact_one!(f(7225450889282194,   710; f64) => b"389190181146",            230);
441     check_exact_one!(f(7225450889282194,   709; f64) => b"1945950905732",           230);
442     check_exact_one!(f(8703372741147379,   117; f64) => b"14460958381605",           52);
443     check_exact_one!(f(8944262675275217, -1001; f64) => b"417367747458531",        -285);
444     check_exact_one!(f(7459803696087692,  -707; f64) => b"1107950772878888",       -196);
445     check_exact_one!(f(6080469016670379,  -381; f64) => b"12345501366327440",       -98);
446     check_exact_one!(f(8385515147034757,   721; f64) => b"925031711960365024",      233);
447     check_exact_one!(f(7514216811389786,  -828; f64) => b"4198047150284889840",    -233);
448     check_exact_one!(f(8397297803260511,  -345; f64) => b"11716315319786511046",    -87);
449     check_exact_one!(f(6733459239310543,   202; f64) => b"432810072844612493629",    77);
450     check_exact_one!(f(8091450587292794,  -473; f64) => b"3317710118160031081518", -126);
451 
452     // [1], Table 4: Stress Inputs for Converting 53-bit Binary to Decimal, > 1/2 ULP
453     check_exact_one!(f(6567258882077402,   952; f64) => b"3",                       303);
454     check_exact_one!(f(6712731423444934,   535; f64) => b"76",                      177);
455     check_exact_one!(f(6712731423444934,   534; f64) => b"378",                     177);
456     check_exact_one!(f(5298405411573037,  -957; f64) => b"4350",                   -272);
457     check_exact_one!(f(5137311167659507,  -144; f64) => b"23037",                   -27);
458     check_exact_one!(f(6722280709661868,   363; f64) => b"126301",                  126);
459     check_exact_one!(f(5344436398034927,  -169; f64) => b"7142211",                 -35);
460     check_exact_one!(f(8369123604277281,  -853; f64) => b"13934574",               -240);
461     check_exact_one!(f(8995822108487663,  -780; f64) => b"141463449",              -218);
462     check_exact_one!(f(8942832835564782,  -383; f64) => b"4539277920",              -99);
463     check_exact_one!(f(8942832835564782,  -384; f64) => b"22696389598",             -99);
464     check_exact_one!(f(8942832835564782,  -385; f64) => b"113481947988",            -99);
465     check_exact_one!(f(6965949469487146,  -249; f64) => b"7700366561890",           -59);
466     check_exact_one!(f(6965949469487146,  -250; f64) => b"38501832809448",          -59);
467     check_exact_one!(f(6965949469487146,  -251; f64) => b"192509164047238",         -59);
468     check_exact_one!(f(7487252720986826,   548; f64) => b"6898586531774201",        181);
469     check_exact_one!(f(5592117679628511,   164; f64) => b"13076622631878654",        66);
470     check_exact_one!(f(8887055249355788,   665; f64) => b"136052020756121240",      217);
471     check_exact_one!(f(6994187472632449,   690; f64) => b"3592810217475959676",     224);
472     check_exact_one!(f(8797576579012143,   588; f64) => b"89125197712484551899",    193);
473     check_exact_one!(f(7363326733505337,   272; f64) => b"558769757362301140950",    98);
474     check_exact_one!(f(8549497411294502,  -448; f64) => b"1176257830728540379990", -118);
475 }
476 
more_shortest_sanity_test<F>(mut f: F) where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),477 pub fn more_shortest_sanity_test<F>(mut f: F)
478 where
479     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
480 {
481     check_shortest!(f{mant: 99_999_999_999_999_999, minus: 1, plus: 1,
482                       exp: 0, inclusive: true} => b"1", 18);
483     check_shortest!(f{mant: 99_999_999_999_999_999, minus: 1, plus: 1,
484                       exp: 0, inclusive: false} => b"99999999999999999", 17);
485 }
486 
to_string_with_parts<F>(mut f: F) -> String where F: for<'a> FnMut(&'a mut [MaybeUninit<u8>], &'a mut [MaybeUninit<Part<'a>>]) -> Formatted<'a>,487 fn to_string_with_parts<F>(mut f: F) -> String
488 where
489     F: for<'a> FnMut(&'a mut [MaybeUninit<u8>], &'a mut [MaybeUninit<Part<'a>>]) -> Formatted<'a>,
490 {
491     let mut buf = [MaybeUninit::new(0); 1024];
492     let mut parts = [MaybeUninit::new(Part::Zero(0)); 16];
493     let formatted = f(&mut buf, &mut parts);
494     let mut ret = vec![0; formatted.len()];
495     assert_eq!(formatted.write(&mut ret), Some(ret.len()));
496     String::from_utf8(ret).unwrap()
497 }
498 
to_shortest_str_test<F>(mut f_: F) where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),499 pub fn to_shortest_str_test<F>(mut f_: F)
500 where
501     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
502 {
503     use core::num::flt2dec::Sign::*;
504 
505     fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
506     where
507         T: DecodableFloat,
508         F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
509     {
510         to_string_with_parts(|buf, parts| {
511             to_shortest_str(|d, b| f(d, b), v, sign, frac_digits, buf, parts)
512         })
513     }
514 
515     let f = &mut f_;
516 
517     assert_eq!(to_string(f, 0.0, Minus, 0), "0");
518     assert_eq!(to_string(f, 0.0, Minus, 0), "0");
519     assert_eq!(to_string(f, 0.0, MinusPlus, 0), "+0");
520     assert_eq!(to_string(f, -0.0, Minus, 0), "-0");
521     assert_eq!(to_string(f, -0.0, MinusPlus, 0), "-0");
522     assert_eq!(to_string(f, 0.0, Minus, 1), "0.0");
523     assert_eq!(to_string(f, 0.0, Minus, 1), "0.0");
524     assert_eq!(to_string(f, 0.0, MinusPlus, 1), "+0.0");
525     assert_eq!(to_string(f, -0.0, Minus, 8), "-0.00000000");
526     assert_eq!(to_string(f, -0.0, MinusPlus, 8), "-0.00000000");
527 
528     assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf");
529     assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf");
530     assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 0), "+inf");
531     assert_eq!(to_string(f, 0.0 / 0.0, Minus, 0), "NaN");
532     assert_eq!(to_string(f, 0.0 / 0.0, Minus, 1), "NaN");
533     assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 64), "NaN");
534     assert_eq!(to_string(f, -1.0 / 0.0, Minus, 0), "-inf");
535     assert_eq!(to_string(f, -1.0 / 0.0, Minus, 1), "-inf");
536     assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64), "-inf");
537 
538     assert_eq!(to_string(f, 3.14, Minus, 0), "3.14");
539     assert_eq!(to_string(f, 3.14, Minus, 0), "3.14");
540     assert_eq!(to_string(f, 3.14, MinusPlus, 0), "+3.14");
541     assert_eq!(to_string(f, -3.14, Minus, 0), "-3.14");
542     assert_eq!(to_string(f, -3.14, Minus, 0), "-3.14");
543     assert_eq!(to_string(f, -3.14, MinusPlus, 0), "-3.14");
544     assert_eq!(to_string(f, 3.14, Minus, 1), "3.14");
545     assert_eq!(to_string(f, 3.14, Minus, 2), "3.14");
546     assert_eq!(to_string(f, 3.14, MinusPlus, 4), "+3.1400");
547     assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000");
548     assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000");
549     assert_eq!(to_string(f, -3.14, MinusPlus, 8), "-3.14000000");
550 
551     assert_eq!(to_string(f, 7.5e-11, Minus, 0), "0.000000000075");
552     assert_eq!(to_string(f, 7.5e-11, Minus, 3), "0.000000000075");
553     assert_eq!(to_string(f, 7.5e-11, Minus, 12), "0.000000000075");
554     assert_eq!(to_string(f, 7.5e-11, Minus, 13), "0.0000000000750");
555 
556     assert_eq!(to_string(f, 1.9971e20, Minus, 0), "199710000000000000000");
557     assert_eq!(to_string(f, 1.9971e20, Minus, 1), "199710000000000000000.0");
558     assert_eq!(to_string(f, 1.9971e20, Minus, 8), "199710000000000000000.00000000");
559 
560     assert_eq!(to_string(f, f32::MAX, Minus, 0), format!("34028235{:0>31}", ""));
561     assert_eq!(to_string(f, f32::MAX, Minus, 1), format!("34028235{:0>31}.0", ""));
562     assert_eq!(to_string(f, f32::MAX, Minus, 8), format!("34028235{:0>31}.00000000", ""));
563 
564     let minf32 = ldexp_f32(1.0, -149);
565     assert_eq!(to_string(f, minf32, Minus, 0), format!("0.{:0>44}1", ""));
566     assert_eq!(to_string(f, minf32, Minus, 45), format!("0.{:0>44}1", ""));
567     assert_eq!(to_string(f, minf32, Minus, 46), format!("0.{:0>44}10", ""));
568 
569     assert_eq!(to_string(f, f64::MAX, Minus, 0), format!("17976931348623157{:0>292}", ""));
570     assert_eq!(to_string(f, f64::MAX, Minus, 1), format!("17976931348623157{:0>292}.0", ""));
571     assert_eq!(to_string(f, f64::MAX, Minus, 8), format!("17976931348623157{:0>292}.00000000", ""));
572 
573     let minf64 = ldexp_f64(1.0, -1074);
574     assert_eq!(to_string(f, minf64, Minus, 0), format!("0.{:0>323}5", ""));
575     assert_eq!(to_string(f, minf64, Minus, 324), format!("0.{:0>323}5", ""));
576     assert_eq!(to_string(f, minf64, Minus, 325), format!("0.{:0>323}50", ""));
577 
578     if cfg!(miri) {
579         // Miri is too slow
580         return;
581     }
582 
583     // very large output
584     assert_eq!(to_string(f, 1.1, Minus, 80000), format!("1.1{:0>79999}", ""));
585 }
586 
to_shortest_exp_str_test<F>(mut f_: F) where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),587 pub fn to_shortest_exp_str_test<F>(mut f_: F)
588 where
589     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
590 {
591     use core::num::flt2dec::Sign::*;
592 
593     fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: bool) -> String
594     where
595         T: DecodableFloat,
596         F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
597     {
598         to_string_with_parts(|buf, parts| {
599             to_shortest_exp_str(|d, b| f(d, b), v, sign, exp_bounds, upper, buf, parts)
600         })
601     }
602 
603     let f = &mut f_;
604 
605     assert_eq!(to_string(f, 0.0, Minus, (-4, 16), false), "0");
606     assert_eq!(to_string(f, 0.0, Minus, (-4, 16), false), "0");
607     assert_eq!(to_string(f, 0.0, MinusPlus, (-4, 16), false), "+0");
608     assert_eq!(to_string(f, -0.0, Minus, (-4, 16), false), "-0");
609     assert_eq!(to_string(f, -0.0, MinusPlus, (-4, 16), false), "-0");
610     assert_eq!(to_string(f, 0.0, Minus, (0, 0), true), "0E0");
611     assert_eq!(to_string(f, 0.0, Minus, (0, 0), false), "0e0");
612     assert_eq!(to_string(f, 0.0, MinusPlus, (5, 9), false), "+0e0");
613     assert_eq!(to_string(f, -0.0, Minus, (0, 0), true), "-0E0");
614     assert_eq!(to_string(f, -0.0, MinusPlus, (5, 9), false), "-0e0");
615 
616     assert_eq!(to_string(f, 1.0 / 0.0, Minus, (-4, 16), false), "inf");
617     assert_eq!(to_string(f, 1.0 / 0.0, Minus, (-4, 16), true), "inf");
618     assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, (-4, 16), true), "+inf");
619     assert_eq!(to_string(f, 0.0 / 0.0, Minus, (0, 0), false), "NaN");
620     assert_eq!(to_string(f, 0.0 / 0.0, Minus, (0, 0), true), "NaN");
621     assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, (5, 9), true), "NaN");
622     assert_eq!(to_string(f, -1.0 / 0.0, Minus, (0, 0), false), "-inf");
623     assert_eq!(to_string(f, -1.0 / 0.0, Minus, (0, 0), true), "-inf");
624     assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, (5, 9), true), "-inf");
625 
626     assert_eq!(to_string(f, 3.14, Minus, (-4, 16), false), "3.14");
627     assert_eq!(to_string(f, 3.14, MinusPlus, (-4, 16), false), "+3.14");
628     assert_eq!(to_string(f, -3.14, Minus, (-4, 16), false), "-3.14");
629     assert_eq!(to_string(f, -3.14, MinusPlus, (-4, 16), false), "-3.14");
630     assert_eq!(to_string(f, 3.14, Minus, (0, 0), true), "3.14E0");
631     assert_eq!(to_string(f, 3.14, Minus, (0, 0), false), "3.14e0");
632     assert_eq!(to_string(f, 3.14, MinusPlus, (5, 9), false), "+3.14e0");
633     assert_eq!(to_string(f, -3.14, Minus, (0, 0), true), "-3.14E0");
634     assert_eq!(to_string(f, -3.14, Minus, (0, 0), false), "-3.14e0");
635     assert_eq!(to_string(f, -3.14, MinusPlus, (5, 9), false), "-3.14e0");
636 
637     assert_eq!(to_string(f, 0.1, Minus, (-4, 16), false), "0.1");
638     assert_eq!(to_string(f, 0.1, Minus, (-4, 16), false), "0.1");
639     assert_eq!(to_string(f, 0.1, MinusPlus, (-4, 16), false), "+0.1");
640     assert_eq!(to_string(f, -0.1, Minus, (-4, 16), false), "-0.1");
641     assert_eq!(to_string(f, -0.1, MinusPlus, (-4, 16), false), "-0.1");
642     assert_eq!(to_string(f, 0.1, Minus, (0, 0), true), "1E-1");
643     assert_eq!(to_string(f, 0.1, Minus, (0, 0), false), "1e-1");
644     assert_eq!(to_string(f, 0.1, MinusPlus, (5, 9), false), "+1e-1");
645     assert_eq!(to_string(f, -0.1, Minus, (0, 0), true), "-1E-1");
646     assert_eq!(to_string(f, -0.1, Minus, (0, 0), false), "-1e-1");
647     assert_eq!(to_string(f, -0.1, MinusPlus, (5, 9), false), "-1e-1");
648 
649     assert_eq!(to_string(f, 7.5e-11, Minus, (-4, 16), false), "7.5e-11");
650     assert_eq!(to_string(f, 7.5e-11, Minus, (-11, 10), false), "0.000000000075");
651     assert_eq!(to_string(f, 7.5e-11, Minus, (-10, 11), false), "7.5e-11");
652 
653     assert_eq!(to_string(f, 1.9971e20, Minus, (-4, 16), false), "1.9971e20");
654     assert_eq!(to_string(f, 1.9971e20, Minus, (-20, 21), false), "199710000000000000000");
655     assert_eq!(to_string(f, 1.9971e20, Minus, (-21, 20), false), "1.9971e20");
656 
657     // the true value of 1.0e23f64 is less than 10^23, but that shouldn't matter here
658     assert_eq!(to_string(f, 1.0e23, Minus, (22, 23), false), "1e23");
659     assert_eq!(to_string(f, 1.0e23, Minus, (23, 24), false), "100000000000000000000000");
660     assert_eq!(to_string(f, 1.0e23, Minus, (24, 25), false), "1e23");
661 
662     assert_eq!(to_string(f, f32::MAX, Minus, (-4, 16), false), "3.4028235e38");
663     assert_eq!(to_string(f, f32::MAX, Minus, (-39, 38), false), "3.4028235e38");
664     assert_eq!(to_string(f, f32::MAX, Minus, (-38, 39), false), format!("34028235{:0>31}", ""));
665 
666     let minf32 = ldexp_f32(1.0, -149);
667     assert_eq!(to_string(f, minf32, Minus, (-4, 16), false), "1e-45");
668     assert_eq!(to_string(f, minf32, Minus, (-44, 45), false), "1e-45");
669     assert_eq!(to_string(f, minf32, Minus, (-45, 44), false), format!("0.{:0>44}1", ""));
670 
671     assert_eq!(to_string(f, f64::MAX, Minus, (-4, 16), false), "1.7976931348623157e308");
672     assert_eq!(
673         to_string(f, f64::MAX, Minus, (-308, 309), false),
674         format!("17976931348623157{:0>292}", "")
675     );
676     assert_eq!(to_string(f, f64::MAX, Minus, (-309, 308), false), "1.7976931348623157e308");
677 
678     let minf64 = ldexp_f64(1.0, -1074);
679     assert_eq!(to_string(f, minf64, Minus, (-4, 16), false), "5e-324");
680     assert_eq!(to_string(f, minf64, Minus, (-324, 323), false), format!("0.{:0>323}5", ""));
681     assert_eq!(to_string(f, minf64, Minus, (-323, 324), false), "5e-324");
682 
683     assert_eq!(to_string(f, 1.1, Minus, (i16::MIN, i16::MAX), false), "1.1");
684 }
685 
to_exact_exp_str_test<F>(mut f_: F) where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),686 pub fn to_exact_exp_str_test<F>(mut f_: F)
687 where
688     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
689 {
690     use core::num::flt2dec::Sign::*;
691 
692     fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) -> String
693     where
694         T: DecodableFloat,
695         F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
696     {
697         to_string_with_parts(|buf, parts| {
698             to_exact_exp_str(|d, b, l| f(d, b, l), v, sign, ndigits, upper, buf, parts)
699         })
700     }
701 
702     let f = &mut f_;
703 
704     assert_eq!(to_string(f, 0.0, Minus, 1, true), "0E0");
705     assert_eq!(to_string(f, 0.0, Minus, 1, false), "0e0");
706     assert_eq!(to_string(f, 0.0, MinusPlus, 1, false), "+0e0");
707     assert_eq!(to_string(f, -0.0, Minus, 1, true), "-0E0");
708     assert_eq!(to_string(f, -0.0, MinusPlus, 1, false), "-0e0");
709     assert_eq!(to_string(f, 0.0, Minus, 2, true), "0.0E0");
710     assert_eq!(to_string(f, 0.0, Minus, 2, false), "0.0e0");
711     assert_eq!(to_string(f, 0.0, MinusPlus, 2, false), "+0.0e0");
712     assert_eq!(to_string(f, -0.0, Minus, 8, false), "-0.0000000e0");
713     assert_eq!(to_string(f, -0.0, MinusPlus, 8, false), "-0.0000000e0");
714 
715     assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1, false), "inf");
716     assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1, true), "inf");
717     assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 1, true), "+inf");
718     assert_eq!(to_string(f, 0.0 / 0.0, Minus, 8, false), "NaN");
719     assert_eq!(to_string(f, 0.0 / 0.0, Minus, 8, true), "NaN");
720     assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8, true), "NaN");
721     assert_eq!(to_string(f, -1.0 / 0.0, Minus, 64, false), "-inf");
722     assert_eq!(to_string(f, -1.0 / 0.0, Minus, 64, true), "-inf");
723     assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64, true), "-inf");
724 
725     assert_eq!(to_string(f, 3.14, Minus, 1, true), "3E0");
726     assert_eq!(to_string(f, 3.14, Minus, 1, false), "3e0");
727     assert_eq!(to_string(f, 3.14, MinusPlus, 1, false), "+3e0");
728     assert_eq!(to_string(f, -3.14, Minus, 2, true), "-3.1E0");
729     assert_eq!(to_string(f, -3.14, Minus, 2, false), "-3.1e0");
730     assert_eq!(to_string(f, -3.14, MinusPlus, 2, false), "-3.1e0");
731     assert_eq!(to_string(f, 3.14, Minus, 3, true), "3.14E0");
732     assert_eq!(to_string(f, 3.14, Minus, 3, false), "3.14e0");
733     assert_eq!(to_string(f, 3.14, MinusPlus, 3, false), "+3.14e0");
734     assert_eq!(to_string(f, -3.14, Minus, 4, true), "-3.140E0");
735     assert_eq!(to_string(f, -3.14, Minus, 4, false), "-3.140e0");
736     assert_eq!(to_string(f, -3.14, MinusPlus, 4, false), "-3.140e0");
737 
738     assert_eq!(to_string(f, 0.195, Minus, 1, false), "2e-1");
739     assert_eq!(to_string(f, 0.195, Minus, 1, true), "2E-1");
740     assert_eq!(to_string(f, 0.195, MinusPlus, 1, true), "+2E-1");
741     assert_eq!(to_string(f, -0.195, Minus, 2, false), "-2.0e-1");
742     assert_eq!(to_string(f, -0.195, Minus, 2, true), "-2.0E-1");
743     assert_eq!(to_string(f, -0.195, MinusPlus, 2, true), "-2.0E-1");
744     assert_eq!(to_string(f, 0.195, Minus, 3, false), "1.95e-1");
745     assert_eq!(to_string(f, 0.195, Minus, 3, true), "1.95E-1");
746     assert_eq!(to_string(f, 0.195, MinusPlus, 3, true), "+1.95E-1");
747     assert_eq!(to_string(f, -0.195, Minus, 4, false), "-1.950e-1");
748     assert_eq!(to_string(f, -0.195, Minus, 4, true), "-1.950E-1");
749     assert_eq!(to_string(f, -0.195, MinusPlus, 4, true), "-1.950E-1");
750 
751     assert_eq!(to_string(f, 9.5, Minus, 1, false), "1e1");
752     assert_eq!(to_string(f, 9.5, Minus, 2, false), "9.5e0");
753     assert_eq!(to_string(f, 9.5, Minus, 3, false), "9.50e0");
754     assert_eq!(to_string(f, 9.5, Minus, 30, false), "9.50000000000000000000000000000e0");
755 
756     assert_eq!(to_string(f, 1.0e25, Minus, 1, false), "1e25");
757     assert_eq!(to_string(f, 1.0e25, Minus, 2, false), "1.0e25");
758     assert_eq!(to_string(f, 1.0e25, Minus, 15, false), "1.00000000000000e25");
759     assert_eq!(to_string(f, 1.0e25, Minus, 16, false), "1.000000000000000e25");
760     assert_eq!(to_string(f, 1.0e25, Minus, 17, false), "1.0000000000000001e25");
761     assert_eq!(to_string(f, 1.0e25, Minus, 18, false), "1.00000000000000009e25");
762     assert_eq!(to_string(f, 1.0e25, Minus, 19, false), "1.000000000000000091e25");
763     assert_eq!(to_string(f, 1.0e25, Minus, 20, false), "1.0000000000000000906e25");
764     assert_eq!(to_string(f, 1.0e25, Minus, 21, false), "1.00000000000000009060e25");
765     assert_eq!(to_string(f, 1.0e25, Minus, 22, false), "1.000000000000000090597e25");
766     assert_eq!(to_string(f, 1.0e25, Minus, 23, false), "1.0000000000000000905970e25");
767     assert_eq!(to_string(f, 1.0e25, Minus, 24, false), "1.00000000000000009059697e25");
768     assert_eq!(to_string(f, 1.0e25, Minus, 25, false), "1.000000000000000090596966e25");
769     assert_eq!(to_string(f, 1.0e25, Minus, 26, false), "1.0000000000000000905969664e25");
770     assert_eq!(to_string(f, 1.0e25, Minus, 27, false), "1.00000000000000009059696640e25");
771     assert_eq!(to_string(f, 1.0e25, Minus, 30, false), "1.00000000000000009059696640000e25");
772 
773     assert_eq!(to_string(f, 1.0e-6, Minus, 1, false), "1e-6");
774     assert_eq!(to_string(f, 1.0e-6, Minus, 2, false), "1.0e-6");
775     assert_eq!(to_string(f, 1.0e-6, Minus, 16, false), "1.000000000000000e-6");
776     assert_eq!(to_string(f, 1.0e-6, Minus, 17, false), "9.9999999999999995e-7");
777     assert_eq!(to_string(f, 1.0e-6, Minus, 18, false), "9.99999999999999955e-7");
778     assert_eq!(to_string(f, 1.0e-6, Minus, 19, false), "9.999999999999999547e-7");
779     assert_eq!(to_string(f, 1.0e-6, Minus, 20, false), "9.9999999999999995475e-7");
780     assert_eq!(to_string(f, 1.0e-6, Minus, 30, false), "9.99999999999999954748111825886e-7");
781     assert_eq!(
782         to_string(f, 1.0e-6, Minus, 40, false),
783         "9.999999999999999547481118258862586856139e-7"
784     );
785     assert_eq!(
786         to_string(f, 1.0e-6, Minus, 50, false),
787         "9.9999999999999995474811182588625868561393872369081e-7"
788     );
789     assert_eq!(
790         to_string(f, 1.0e-6, Minus, 60, false),
791         "9.99999999999999954748111825886258685613938723690807819366455e-7"
792     );
793     assert_eq!(
794         to_string(f, 1.0e-6, Minus, 70, false),
795         "9.999999999999999547481118258862586856139387236908078193664550781250000e-7"
796     );
797 
798     assert_eq!(to_string(f, f32::MAX, Minus, 1, false), "3e38");
799     assert_eq!(to_string(f, f32::MAX, Minus, 2, false), "3.4e38");
800     assert_eq!(to_string(f, f32::MAX, Minus, 4, false), "3.403e38");
801     assert_eq!(to_string(f, f32::MAX, Minus, 8, false), "3.4028235e38");
802     assert_eq!(to_string(f, f32::MAX, Minus, 16, false), "3.402823466385289e38");
803     assert_eq!(to_string(f, f32::MAX, Minus, 32, false), "3.4028234663852885981170418348452e38");
804     assert_eq!(
805         to_string(f, f32::MAX, Minus, 64, false),
806         "3.402823466385288598117041834845169254400000000000000000000000000e38"
807     );
808 
809     let minf32 = ldexp_f32(1.0, -149);
810     assert_eq!(to_string(f, minf32, Minus, 1, false), "1e-45");
811     assert_eq!(to_string(f, minf32, Minus, 2, false), "1.4e-45");
812     assert_eq!(to_string(f, minf32, Minus, 4, false), "1.401e-45");
813     assert_eq!(to_string(f, minf32, Minus, 8, false), "1.4012985e-45");
814     assert_eq!(to_string(f, minf32, Minus, 16, false), "1.401298464324817e-45");
815     assert_eq!(to_string(f, minf32, Minus, 32, false), "1.4012984643248170709237295832899e-45");
816     assert_eq!(
817         to_string(f, minf32, Minus, 64, false),
818         "1.401298464324817070923729583289916131280261941876515771757068284e-45"
819     );
820     assert_eq!(
821         to_string(f, minf32, Minus, 128, false),
822         "1.401298464324817070923729583289916131280261941876515771757068283\
823                  8897910826858606014866381883621215820312500000000000000000000000e-45"
824     );
825 
826     if cfg!(miri) {
827         // Miri is too slow
828         return;
829     }
830 
831     assert_eq!(to_string(f, f64::MAX, Minus, 1, false), "2e308");
832     assert_eq!(to_string(f, f64::MAX, Minus, 2, false), "1.8e308");
833     assert_eq!(to_string(f, f64::MAX, Minus, 4, false), "1.798e308");
834     assert_eq!(to_string(f, f64::MAX, Minus, 8, false), "1.7976931e308");
835     assert_eq!(to_string(f, f64::MAX, Minus, 16, false), "1.797693134862316e308");
836     assert_eq!(to_string(f, f64::MAX, Minus, 32, false), "1.7976931348623157081452742373170e308");
837     assert_eq!(
838         to_string(f, f64::MAX, Minus, 64, false),
839         "1.797693134862315708145274237317043567980705675258449965989174768e308"
840     );
841     assert_eq!(
842         to_string(f, f64::MAX, Minus, 128, false),
843         "1.797693134862315708145274237317043567980705675258449965989174768\
844                  0315726078002853876058955863276687817154045895351438246423432133e308"
845     );
846     assert_eq!(
847         to_string(f, f64::MAX, Minus, 256, false),
848         "1.797693134862315708145274237317043567980705675258449965989174768\
849                  0315726078002853876058955863276687817154045895351438246423432132\
850                  6889464182768467546703537516986049910576551282076245490090389328\
851                  9440758685084551339423045832369032229481658085593321233482747978e308"
852     );
853     assert_eq!(
854         to_string(f, f64::MAX, Minus, 512, false),
855         "1.797693134862315708145274237317043567980705675258449965989174768\
856                  0315726078002853876058955863276687817154045895351438246423432132\
857                  6889464182768467546703537516986049910576551282076245490090389328\
858                  9440758685084551339423045832369032229481658085593321233482747978\
859                  2620414472316873817718091929988125040402618412485836800000000000\
860                  0000000000000000000000000000000000000000000000000000000000000000\
861                  0000000000000000000000000000000000000000000000000000000000000000\
862                  0000000000000000000000000000000000000000000000000000000000000000e308"
863     );
864 
865     // okay, this is becoming tough. fortunately for us, this is almost the worst case.
866     let minf64 = ldexp_f64(1.0, -1074);
867     assert_eq!(to_string(f, minf64, Minus, 1, false), "5e-324");
868     assert_eq!(to_string(f, minf64, Minus, 2, false), "4.9e-324");
869     assert_eq!(to_string(f, minf64, Minus, 4, false), "4.941e-324");
870     assert_eq!(to_string(f, minf64, Minus, 8, false), "4.9406565e-324");
871     assert_eq!(to_string(f, minf64, Minus, 16, false), "4.940656458412465e-324");
872     assert_eq!(to_string(f, minf64, Minus, 32, false), "4.9406564584124654417656879286822e-324");
873     assert_eq!(
874         to_string(f, minf64, Minus, 64, false),
875         "4.940656458412465441765687928682213723650598026143247644255856825e-324"
876     );
877     assert_eq!(
878         to_string(f, minf64, Minus, 128, false),
879         "4.940656458412465441765687928682213723650598026143247644255856825\
880                  0067550727020875186529983636163599237979656469544571773092665671e-324"
881     );
882     assert_eq!(
883         to_string(f, minf64, Minus, 256, false),
884         "4.940656458412465441765687928682213723650598026143247644255856825\
885                  0067550727020875186529983636163599237979656469544571773092665671\
886                  0355939796398774796010781878126300713190311404527845817167848982\
887                  1036887186360569987307230500063874091535649843873124733972731696e-324"
888     );
889     assert_eq!(
890         to_string(f, minf64, Minus, 512, false),
891         "4.940656458412465441765687928682213723650598026143247644255856825\
892                  0067550727020875186529983636163599237979656469544571773092665671\
893                  0355939796398774796010781878126300713190311404527845817167848982\
894                  1036887186360569987307230500063874091535649843873124733972731696\
895                  1514003171538539807412623856559117102665855668676818703956031062\
896                  4931945271591492455329305456544401127480129709999541931989409080\
897                  4165633245247571478690147267801593552386115501348035264934720193\
898                  7902681071074917033322268447533357208324319360923828934583680601e-324"
899     );
900     assert_eq!(
901         to_string(f, minf64, Minus, 1024, false),
902         "4.940656458412465441765687928682213723650598026143247644255856825\
903                  0067550727020875186529983636163599237979656469544571773092665671\
904                  0355939796398774796010781878126300713190311404527845817167848982\
905                  1036887186360569987307230500063874091535649843873124733972731696\
906                  1514003171538539807412623856559117102665855668676818703956031062\
907                  4931945271591492455329305456544401127480129709999541931989409080\
908                  4165633245247571478690147267801593552386115501348035264934720193\
909                  7902681071074917033322268447533357208324319360923828934583680601\
910                  0601150616980975307834227731832924790498252473077637592724787465\
911                  6084778203734469699533647017972677717585125660551199131504891101\
912                  4510378627381672509558373897335989936648099411642057026370902792\
913                  4276754456522908753868250641971826553344726562500000000000000000\
914                  0000000000000000000000000000000000000000000000000000000000000000\
915                  0000000000000000000000000000000000000000000000000000000000000000\
916                  0000000000000000000000000000000000000000000000000000000000000000\
917                  0000000000000000000000000000000000000000000000000000000000000000e-324"
918     );
919 
920     // very large output
921     assert_eq!(to_string(f, 0.0, Minus, 80000, false), format!("0.{:0>79999}e0", ""));
922     assert_eq!(to_string(f, 1.0e1, Minus, 80000, false), format!("1.{:0>79999}e1", ""));
923     assert_eq!(to_string(f, 1.0e0, Minus, 80000, false), format!("1.{:0>79999}e0", ""));
924     assert_eq!(
925         to_string(f, 1.0e-1, Minus, 80000, false),
926         format!(
927             "1.000000000000000055511151231257827021181583404541015625{:0>79945}\
928                         e-1",
929             ""
930         )
931     );
932     assert_eq!(
933         to_string(f, 1.0e-20, Minus, 80000, false),
934         format!(
935             "9.999999999999999451532714542095716517295037027873924471077157760\
936                          66783064379706047475337982177734375{:0>79901}e-21",
937             ""
938         )
939     );
940 }
941 
to_exact_fixed_str_test<F>(mut f_: F) where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),942 pub fn to_exact_fixed_str_test<F>(mut f_: F)
943 where
944     F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
945 {
946     use core::num::flt2dec::Sign::*;
947 
948     fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
949     where
950         T: DecodableFloat,
951         F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
952     {
953         to_string_with_parts(|buf, parts| {
954             to_exact_fixed_str(|d, b, l| f(d, b, l), v, sign, frac_digits, buf, parts)
955         })
956     }
957 
958     let f = &mut f_;
959 
960     assert_eq!(to_string(f, 0.0, Minus, 0), "0");
961     assert_eq!(to_string(f, 0.0, MinusPlus, 0), "+0");
962     assert_eq!(to_string(f, -0.0, Minus, 0), "-0");
963     assert_eq!(to_string(f, -0.0, MinusPlus, 0), "-0");
964     assert_eq!(to_string(f, 0.0, Minus, 1), "0.0");
965     assert_eq!(to_string(f, 0.0, MinusPlus, 1), "+0.0");
966     assert_eq!(to_string(f, -0.0, Minus, 8), "-0.00000000");
967     assert_eq!(to_string(f, -0.0, MinusPlus, 8), "-0.00000000");
968 
969     assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf");
970     assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1), "inf");
971     assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 64), "+inf");
972     assert_eq!(to_string(f, 0.0 / 0.0, Minus, 0), "NaN");
973     assert_eq!(to_string(f, 0.0 / 0.0, Minus, 1), "NaN");
974     assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 64), "NaN");
975     assert_eq!(to_string(f, -1.0 / 0.0, Minus, 0), "-inf");
976     assert_eq!(to_string(f, -1.0 / 0.0, Minus, 1), "-inf");
977     assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64), "-inf");
978 
979     assert_eq!(to_string(f, 3.14, Minus, 0), "3");
980     assert_eq!(to_string(f, 3.14, Minus, 0), "3");
981     assert_eq!(to_string(f, 3.14, MinusPlus, 0), "+3");
982     assert_eq!(to_string(f, -3.14, Minus, 0), "-3");
983     assert_eq!(to_string(f, -3.14, Minus, 0), "-3");
984     assert_eq!(to_string(f, -3.14, MinusPlus, 0), "-3");
985     assert_eq!(to_string(f, 3.14, Minus, 1), "3.1");
986     assert_eq!(to_string(f, 3.14, Minus, 2), "3.14");
987     assert_eq!(to_string(f, 3.14, MinusPlus, 4), "+3.1400");
988     assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000");
989     assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000");
990     assert_eq!(to_string(f, -3.14, MinusPlus, 8), "-3.14000000");
991 
992     assert_eq!(to_string(f, 0.195, Minus, 0), "0");
993     assert_eq!(to_string(f, 0.195, MinusPlus, 0), "+0");
994     assert_eq!(to_string(f, -0.195, Minus, 0), "-0");
995     assert_eq!(to_string(f, -0.195, Minus, 0), "-0");
996     assert_eq!(to_string(f, -0.195, MinusPlus, 0), "-0");
997     assert_eq!(to_string(f, 0.195, Minus, 1), "0.2");
998     assert_eq!(to_string(f, 0.195, Minus, 2), "0.20");
999     assert_eq!(to_string(f, 0.195, MinusPlus, 4), "+0.1950");
1000     assert_eq!(to_string(f, -0.195, Minus, 5), "-0.19500");
1001     assert_eq!(to_string(f, -0.195, Minus, 6), "-0.195000");
1002     assert_eq!(to_string(f, -0.195, MinusPlus, 8), "-0.19500000");
1003 
1004     assert_eq!(to_string(f, 999.5, Minus, 0), "1000");
1005     assert_eq!(to_string(f, 999.5, Minus, 1), "999.5");
1006     assert_eq!(to_string(f, 999.5, Minus, 2), "999.50");
1007     assert_eq!(to_string(f, 999.5, Minus, 3), "999.500");
1008     assert_eq!(to_string(f, 999.5, Minus, 30), "999.500000000000000000000000000000");
1009 
1010     assert_eq!(to_string(f, 0.5, Minus, 0), "1");
1011     assert_eq!(to_string(f, 0.5, Minus, 1), "0.5");
1012     assert_eq!(to_string(f, 0.5, Minus, 2), "0.50");
1013     assert_eq!(to_string(f, 0.5, Minus, 3), "0.500");
1014 
1015     assert_eq!(to_string(f, 0.95, Minus, 0), "1");
1016     assert_eq!(to_string(f, 0.95, Minus, 1), "0.9"); // because it really is less than 0.95
1017     assert_eq!(to_string(f, 0.95, Minus, 2), "0.95");
1018     assert_eq!(to_string(f, 0.95, Minus, 3), "0.950");
1019     assert_eq!(to_string(f, 0.95, Minus, 10), "0.9500000000");
1020     assert_eq!(to_string(f, 0.95, Minus, 30), "0.949999999999999955591079014994");
1021 
1022     assert_eq!(to_string(f, 0.095, Minus, 0), "0");
1023     assert_eq!(to_string(f, 0.095, Minus, 1), "0.1");
1024     assert_eq!(to_string(f, 0.095, Minus, 2), "0.10");
1025     assert_eq!(to_string(f, 0.095, Minus, 3), "0.095");
1026     assert_eq!(to_string(f, 0.095, Minus, 4), "0.0950");
1027     assert_eq!(to_string(f, 0.095, Minus, 10), "0.0950000000");
1028     assert_eq!(to_string(f, 0.095, Minus, 30), "0.095000000000000001110223024625");
1029 
1030     assert_eq!(to_string(f, 0.0095, Minus, 0), "0");
1031     assert_eq!(to_string(f, 0.0095, Minus, 1), "0.0");
1032     assert_eq!(to_string(f, 0.0095, Minus, 2), "0.01");
1033     assert_eq!(to_string(f, 0.0095, Minus, 3), "0.009"); // really is less than 0.0095
1034     assert_eq!(to_string(f, 0.0095, Minus, 4), "0.0095");
1035     assert_eq!(to_string(f, 0.0095, Minus, 5), "0.00950");
1036     assert_eq!(to_string(f, 0.0095, Minus, 10), "0.0095000000");
1037     assert_eq!(to_string(f, 0.0095, Minus, 30), "0.009499999999999999764077607267");
1038 
1039     assert_eq!(to_string(f, 7.5e-11, Minus, 0), "0");
1040     assert_eq!(to_string(f, 7.5e-11, Minus, 3), "0.000");
1041     assert_eq!(to_string(f, 7.5e-11, Minus, 10), "0.0000000001");
1042     assert_eq!(to_string(f, 7.5e-11, Minus, 11), "0.00000000007"); // ditto
1043     assert_eq!(to_string(f, 7.5e-11, Minus, 12), "0.000000000075");
1044     assert_eq!(to_string(f, 7.5e-11, Minus, 13), "0.0000000000750");
1045     assert_eq!(to_string(f, 7.5e-11, Minus, 20), "0.00000000007500000000");
1046     assert_eq!(to_string(f, 7.5e-11, Minus, 30), "0.000000000074999999999999999501");
1047 
1048     assert_eq!(to_string(f, 1.0e25, Minus, 0), "10000000000000000905969664");
1049     assert_eq!(to_string(f, 1.0e25, Minus, 1), "10000000000000000905969664.0");
1050     assert_eq!(to_string(f, 1.0e25, Minus, 3), "10000000000000000905969664.000");
1051 
1052     assert_eq!(to_string(f, 1.0e-6, Minus, 0), "0");
1053     assert_eq!(to_string(f, 1.0e-6, Minus, 3), "0.000");
1054     assert_eq!(to_string(f, 1.0e-6, Minus, 6), "0.000001");
1055     assert_eq!(to_string(f, 1.0e-6, Minus, 9), "0.000001000");
1056     assert_eq!(to_string(f, 1.0e-6, Minus, 12), "0.000001000000");
1057     assert_eq!(to_string(f, 1.0e-6, Minus, 22), "0.0000010000000000000000");
1058     assert_eq!(to_string(f, 1.0e-6, Minus, 23), "0.00000099999999999999995");
1059     assert_eq!(to_string(f, 1.0e-6, Minus, 24), "0.000000999999999999999955");
1060     assert_eq!(to_string(f, 1.0e-6, Minus, 25), "0.0000009999999999999999547");
1061     assert_eq!(to_string(f, 1.0e-6, Minus, 35), "0.00000099999999999999995474811182589");
1062     assert_eq!(to_string(f, 1.0e-6, Minus, 45), "0.000000999999999999999954748111825886258685614");
1063     assert_eq!(
1064         to_string(f, 1.0e-6, Minus, 55),
1065         "0.0000009999999999999999547481118258862586856139387236908"
1066     );
1067     assert_eq!(
1068         to_string(f, 1.0e-6, Minus, 65),
1069         "0.00000099999999999999995474811182588625868561393872369080781936646"
1070     );
1071     assert_eq!(
1072         to_string(f, 1.0e-6, Minus, 75),
1073         "0.000000999999999999999954748111825886258685613938723690807819366455078125000"
1074     );
1075 
1076     assert_eq!(to_string(f, f32::MAX, Minus, 0), "340282346638528859811704183484516925440");
1077     assert_eq!(to_string(f, f32::MAX, Minus, 1), "340282346638528859811704183484516925440.0");
1078     assert_eq!(to_string(f, f32::MAX, Minus, 2), "340282346638528859811704183484516925440.00");
1079 
1080     if cfg!(miri) {
1081         // Miri is too slow
1082         return;
1083     }
1084 
1085     let minf32 = ldexp_f32(1.0, -149);
1086     assert_eq!(to_string(f, minf32, Minus, 0), "0");
1087     assert_eq!(to_string(f, minf32, Minus, 1), "0.0");
1088     assert_eq!(to_string(f, minf32, Minus, 2), "0.00");
1089     assert_eq!(to_string(f, minf32, Minus, 4), "0.0000");
1090     assert_eq!(to_string(f, minf32, Minus, 8), "0.00000000");
1091     assert_eq!(to_string(f, minf32, Minus, 16), "0.0000000000000000");
1092     assert_eq!(to_string(f, minf32, Minus, 32), "0.00000000000000000000000000000000");
1093     assert_eq!(
1094         to_string(f, minf32, Minus, 64),
1095         "0.0000000000000000000000000000000000000000000014012984643248170709"
1096     );
1097     assert_eq!(
1098         to_string(f, minf32, Minus, 128),
1099         "0.0000000000000000000000000000000000000000000014012984643248170709\
1100                   2372958328991613128026194187651577175706828388979108268586060149"
1101     );
1102     assert_eq!(
1103         to_string(f, minf32, Minus, 256),
1104         "0.0000000000000000000000000000000000000000000014012984643248170709\
1105                   2372958328991613128026194187651577175706828388979108268586060148\
1106                   6638188362121582031250000000000000000000000000000000000000000000\
1107                   0000000000000000000000000000000000000000000000000000000000000000"
1108     );
1109 
1110     assert_eq!(
1111         to_string(f, f64::MAX, Minus, 0),
1112         "1797693134862315708145274237317043567980705675258449965989174768\
1113                 0315726078002853876058955863276687817154045895351438246423432132\
1114                 6889464182768467546703537516986049910576551282076245490090389328\
1115                 9440758685084551339423045832369032229481658085593321233482747978\
1116                 26204144723168738177180919299881250404026184124858368"
1117     );
1118     assert_eq!(
1119         to_string(f, f64::MAX, Minus, 10),
1120         "1797693134862315708145274237317043567980705675258449965989174768\
1121                 0315726078002853876058955863276687817154045895351438246423432132\
1122                 6889464182768467546703537516986049910576551282076245490090389328\
1123                 9440758685084551339423045832369032229481658085593321233482747978\
1124                 26204144723168738177180919299881250404026184124858368.0000000000"
1125     );
1126 
1127     let minf64 = ldexp_f64(1.0, -1074);
1128     assert_eq!(to_string(f, minf64, Minus, 0), "0");
1129     assert_eq!(to_string(f, minf64, Minus, 1), "0.0");
1130     assert_eq!(to_string(f, minf64, Minus, 10), "0.0000000000");
1131     assert_eq!(
1132         to_string(f, minf64, Minus, 100),
1133         "0.0000000000000000000000000000000000000000000000000000000000000000\
1134                   000000000000000000000000000000000000"
1135     );
1136     assert_eq!(
1137         to_string(f, minf64, Minus, 1000),
1138         "0.0000000000000000000000000000000000000000000000000000000000000000\
1139                   0000000000000000000000000000000000000000000000000000000000000000\
1140                   0000000000000000000000000000000000000000000000000000000000000000\
1141                   0000000000000000000000000000000000000000000000000000000000000000\
1142                   0000000000000000000000000000000000000000000000000000000000000000\
1143                   0004940656458412465441765687928682213723650598026143247644255856\
1144                   8250067550727020875186529983636163599237979656469544571773092665\
1145                   6710355939796398774796010781878126300713190311404527845817167848\
1146                   9821036887186360569987307230500063874091535649843873124733972731\
1147                   6961514003171538539807412623856559117102665855668676818703956031\
1148                   0624931945271591492455329305456544401127480129709999541931989409\
1149                   0804165633245247571478690147267801593552386115501348035264934720\
1150                   1937902681071074917033322268447533357208324319360923828934583680\
1151                   6010601150616980975307834227731832924790498252473077637592724787\
1152                   4656084778203734469699533647017972677717585125660551199131504891\
1153                   1014510378627381672509558373897335989937"
1154     );
1155 
1156     // very large output
1157     assert_eq!(to_string(f, 0.0, Minus, 80000), format!("0.{:0>80000}", ""));
1158     assert_eq!(to_string(f, 1.0e1, Minus, 80000), format!("10.{:0>80000}", ""));
1159     assert_eq!(to_string(f, 1.0e0, Minus, 80000), format!("1.{:0>80000}", ""));
1160     assert_eq!(
1161         to_string(f, 1.0e-1, Minus, 80000),
1162         format!("0.1000000000000000055511151231257827021181583404541015625{:0>79945}", "")
1163     );
1164     assert_eq!(
1165         to_string(f, 1.0e-20, Minus, 80000),
1166         format!(
1167             "0.0000000000000000000099999999999999994515327145420957165172950370\
1168                           2787392447107715776066783064379706047475337982177734375{:0>79881}",
1169             ""
1170         )
1171     );
1172 }
1173