]> git.proxmox.com Git - rustc.git/blame - library/core/tests/num/flt2dec/mod.rs
New upstream version 1.61.0+dfsg1
[rustc.git] / library / core / tests / num / flt2dec / mod.rs
CommitLineData
1b1a35ee 1use std::mem::MaybeUninit;
ba9703b0 2use std::{fmt, str};
d9579d0f 3
dfeec247 4use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
136023e0 5use core::num::flt2dec::{round_up, Sign, MAX_SIG_DIGITS};
dfeec247
XL
6use core::num::flt2dec::{
7 to_exact_exp_str, to_exact_fixed_str, to_shortest_exp_str, to_shortest_str,
8};
136023e0 9use core::num::fmt::{Formatted, Part};
d9579d0f
AL
10
11pub use test::Bencher;
12
13mod estimator;
d9579d0f
AL
14mod strategy {
15 mod dragon;
16 mod grisu;
17}
0531ce1d 18mod random;
d9579d0f
AL
19
20pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
21 match decode(v).1 {
22 FullDecoded::Finite(decoded) => decoded,
ee023bcb 23 full_decoded => panic!("expected finite, got {full_decoded:?} instead"),
d9579d0f
AL
24 }
25}
26
27macro_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),*) => ({
1b1a35ee
XL
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),
d9579d0f
AL
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),*) => ({
1b1a35ee
XL
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),
d9579d0f
AL
55 expected = (str::from_utf8($buf).unwrap(), $exp),
56 $($key = $val),*);
57 })
58}
59
60macro_rules! try_exact {
61 ($f:ident($decoded:expr) => $buf:expr, $expected:expr, $expectedk:expr;
62 $fmt:expr, $($key:ident = $val:expr),*) => ({
1b1a35ee
XL
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),
d9579d0f
AL
66 expected = (str::from_utf8($expected).unwrap(), $expectedk),
67 $($key = $val),*);
68 })
69}
70
71macro_rules! try_fixed {
72 ($f:ident($decoded:expr) => $buf:expr, $request:expr, $expected:expr, $expectedk:expr;
73 $fmt:expr, $($key:ident = $val:expr),*) => ({
1b1a35ee
XL
74 let (buf, k) = $f($decoded, &mut $buf[..], $request);
75 assert!((buf, k) == ($expected, $expectedk),
76 $fmt, actual = (str::from_utf8(buf).unwrap(), k),
d9579d0f
AL
77 expected = (str::from_utf8($expected).unwrap(), $expectedk),
78 $($key = $val),*);
79 })
80}
81
3157f602
XL
82fn ldexp_f32(a: f32, b: i32) -> f32 {
83 ldexp_f64(a as f64, b) as f32
84}
85
86fn ldexp_f64(a: f64, b: i32) -> f64 {
dfeec247 87 extern "C" {
3157f602
XL
88 fn ldexp(x: f64, n: i32) -> f64;
89 }
60c5eb7d
XL
90 // SAFETY: assuming a correct `ldexp` has been supplied, the given arguments cannot possibly
91 // cause undefined behavior
3157f602
XL
92 unsafe { ldexp(a, b) }
93}
94
d9579d0f 95fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16)
dfeec247
XL
96where
97 T: DecodableFloat,
1b1a35ee 98 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
dfeec247 99{
d9579d0f 100 // use a large enough buffer
1b1a35ee 101 let mut buf = [MaybeUninit::new(b'_'); 1024];
d9579d0f
AL
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) {
7453a54e 109 expected_[..i].copy_from_slice(&expected[..i]);
d9579d0f
AL
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.
dfeec247
XL
114 if !(i + 1 < expected.len()
115 && expected[i - 1] & 1 == 0
116 && expected[i] == b'5'
117 && expected[i + 1] == b' ')
118 {
d9579d0f
AL
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.
1b1a35ee 123 if let Some(_) = round_up(&mut expected_[..i]) {
dfeec247
XL
124 expectedk_ += 1;
125 }
d9579d0f
AL
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 {
dfeec247 159 for i in cut..expected.len() - 1 {
7453a54e 160 expected_[..cut].copy_from_slice(&expected[..cut]);
dfeec247
XL
161 for c in &mut expected_[cut..i] {
162 *c = b'0';
163 }
d9579d0f
AL
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
dfeec247 177trait TestableFloat: DecodableFloat + fmt::Display {
e9174d1e
SL
178 /// Returns `x * 2^exp`. Almost same to `std::{f32,f64}::ldexp`.
179 /// This is used for testing.
180 fn ldexpi(f: i64, exp: isize) -> Self;
181}
182
183impl TestableFloat for f32 {
dfeec247
XL
184 fn ldexpi(f: i64, exp: isize) -> Self {
185 f as Self * (exp as Self).exp2()
186 }
e9174d1e
SL
187}
188
189impl TestableFloat for f64 {
dfeec247
XL
190 fn ldexpi(f: i64, exp: isize) -> Self {
191 f as Self * (exp as Self).exp2()
192 }
e9174d1e
SL
193}
194
d9579d0f 195fn check_exact_one<F, T>(mut f: F, x: i64, e: isize, tstr: &str, expected: &[u8], expectedk: i16)
dfeec247
XL
196where
197 T: TestableFloat,
1b1a35ee 198 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
dfeec247 199{
d9579d0f 200 // use a large enough buffer
1b1a35ee 201 let mut buf = [MaybeUninit::new(b'_'); 1024];
e9174d1e 202 let v: T = TestableFloat::ldexpi(x, e);
d9579d0f
AL
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
213macro_rules! check_exact {
dfeec247
XL
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 };
d9579d0f
AL
217}
218
219macro_rules! check_exact_one {
dfeec247
XL
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 };
d9579d0f
AL
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
dfeec247
XL
233pub fn f32_shortest_sanity_test<F>(mut f: F)
234where
1b1a35ee 235 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
dfeec247 236{
d9579d0f
AL
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
3157f602 261 check_shortest!(f(ldexp_f32(1.0, 25)) => b"33554432", 8);
d9579d0f
AL
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...
3157f602 276 let minf32 = ldexp_f32(1.0, -149);
d9579d0f
AL
277 check_shortest!(f(minf32) => b"1", -44);
278}
279
280pub fn f32_exact_sanity_test<F>(mut f: F)
dfeec247 281where
1b1a35ee 282 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
dfeec247 283{
3157f602 284 let minf32 = ldexp_f32(1.0, -149);
d9579d0f
AL
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
dfeec247
XL
324pub fn f64_shortest_sanity_test<F>(mut f: F)
325where
1b1a35ee 326 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
dfeec247 327{
d9579d0f
AL
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
3157f602 365 check_shortest!(f(ldexp_f64(1.0, 64)) => b"18446744073709552", 20);
d9579d0f
AL
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...
3157f602 386 let minf64 = ldexp_f64(1.0, -1074);
d9579d0f
AL
387 check_shortest!(f(minf64) => b"5", -323);
388}
389
390pub fn f64_exact_sanity_test<F>(mut f: F)
dfeec247 391where
1b1a35ee 392 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
dfeec247 393{
3157f602 394 let minf64 = ldexp_f64(1.0, -1074);
d9579d0f
AL
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
dfeec247
XL
477pub fn more_shortest_sanity_test<F>(mut f: F)
478where
1b1a35ee 479 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
dfeec247 480{
d9579d0f
AL
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
d9579d0f 487fn to_string_with_parts<F>(mut f: F) -> String
dfeec247 488where
1b1a35ee 489 F: for<'a> FnMut(&'a mut [MaybeUninit<u8>], &'a mut [MaybeUninit<Part<'a>>]) -> Formatted<'a>,
dfeec247 490{
1b1a35ee
XL
491 let mut buf = [MaybeUninit::new(0); 1024];
492 let mut parts = [MaybeUninit::new(Part::Zero(0)); 16];
d9579d0f
AL
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
499pub fn to_shortest_str_test<F>(mut f_: F)
dfeec247 500where
1b1a35ee 501 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
dfeec247 502{
d9579d0f
AL
503 use core::num::flt2dec::Sign::*;
504
74b04a01 505 fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
dfeec247
XL
506 where
507 T: DecodableFloat,
1b1a35ee 508 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
dfeec247
XL
509 {
510 to_string_with_parts(|buf, parts| {
74b04a01 511 to_shortest_str(|d, b| f(d, b), v, sign, frac_digits, buf, parts)
dfeec247 512 })
d9579d0f
AL
513 }
514
515 let f = &mut f_;
516
74b04a01 517 assert_eq!(to_string(f, 0.0, Minus, 0), "0");
cdc7bbd5 518 assert_eq!(to_string(f, 0.0, Minus, 0), "0");
74b04a01 519 assert_eq!(to_string(f, 0.0, MinusPlus, 0), "+0");
cdc7bbd5
XL
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");
74b04a01 523 assert_eq!(to_string(f, 0.0, Minus, 1), "0.0");
74b04a01 524 assert_eq!(to_string(f, 0.0, MinusPlus, 1), "+0.0");
cdc7bbd5
XL
525 assert_eq!(to_string(f, -0.0, Minus, 8), "-0.00000000");
526 assert_eq!(to_string(f, -0.0, MinusPlus, 8), "-0.00000000");
74b04a01
XL
527
528 assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf");
cdc7bbd5 529 assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf");
74b04a01 530 assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 0), "+inf");
74b04a01 531 assert_eq!(to_string(f, 0.0 / 0.0, Minus, 0), "NaN");
cdc7bbd5
XL
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");
74b04a01 534 assert_eq!(to_string(f, -1.0 / 0.0, Minus, 0), "-inf");
cdc7bbd5
XL
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");
74b04a01
XL
537
538 assert_eq!(to_string(f, 3.14, Minus, 0), "3.14");
cdc7bbd5 539 assert_eq!(to_string(f, 3.14, Minus, 0), "3.14");
74b04a01 540 assert_eq!(to_string(f, 3.14, MinusPlus, 0), "+3.14");
74b04a01 541 assert_eq!(to_string(f, -3.14, Minus, 0), "-3.14");
cdc7bbd5 542 assert_eq!(to_string(f, -3.14, Minus, 0), "-3.14");
74b04a01 543 assert_eq!(to_string(f, -3.14, MinusPlus, 0), "-3.14");
74b04a01 544 assert_eq!(to_string(f, 3.14, Minus, 1), "3.14");
cdc7bbd5
XL
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");
74b04a01 548 assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000");
74b04a01 549 assert_eq!(to_string(f, -3.14, MinusPlus, 8), "-3.14000000");
74b04a01
XL
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", ""));
d9579d0f 563
3157f602 564 let minf32 = ldexp_f32(1.0, -149);
74b04a01
XL
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", ""));
d9579d0f 568
74b04a01
XL
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", ""));
d9579d0f 572
3157f602 573 let minf64 = ldexp_f64(1.0, -1074);
74b04a01
XL
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", ""));
d9579d0f 577
dfeec247
XL
578 if cfg!(miri) {
579 // Miri is too slow
416331ca
XL
580 return;
581 }
582
d9579d0f 583 // very large output
74b04a01 584 assert_eq!(to_string(f, 1.1, Minus, 80000), format!("1.1{:0>79999}", ""));
d9579d0f
AL
585}
586
587pub fn to_shortest_exp_str_test<F>(mut f_: F)
dfeec247 588where
1b1a35ee 589 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
dfeec247 590{
d9579d0f
AL
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
dfeec247
XL
594 where
595 T: DecodableFloat,
1b1a35ee 596 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
dfeec247
XL
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 })
d9579d0f
AL
601 }
602
603 let f = &mut f_;
604
dfeec247 605 assert_eq!(to_string(f, 0.0, Minus, (-4, 16), false), "0");
cdc7bbd5 606 assert_eq!(to_string(f, 0.0, Minus, (-4, 16), false), "0");
dfeec247 607 assert_eq!(to_string(f, 0.0, MinusPlus, (-4, 16), false), "+0");
cdc7bbd5
XL
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");
dfeec247 610 assert_eq!(to_string(f, 0.0, Minus, (0, 0), true), "0E0");
cdc7bbd5
XL
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");
dfeec247
XL
615
616 assert_eq!(to_string(f, 1.0 / 0.0, Minus, (-4, 16), false), "inf");
cdc7bbd5
XL
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");
dfeec247 619 assert_eq!(to_string(f, 0.0 / 0.0, Minus, (0, 0), false), "NaN");
cdc7bbd5
XL
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");
dfeec247 622 assert_eq!(to_string(f, -1.0 / 0.0, Minus, (0, 0), false), "-inf");
cdc7bbd5
XL
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");
dfeec247
XL
625
626 assert_eq!(to_string(f, 3.14, Minus, (-4, 16), false), "3.14");
dfeec247 627 assert_eq!(to_string(f, 3.14, MinusPlus, (-4, 16), false), "+3.14");
dfeec247 628 assert_eq!(to_string(f, -3.14, Minus, (-4, 16), false), "-3.14");
dfeec247 629 assert_eq!(to_string(f, -3.14, MinusPlus, (-4, 16), false), "-3.14");
dfeec247 630 assert_eq!(to_string(f, 3.14, Minus, (0, 0), true), "3.14E0");
cdc7bbd5
XL
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");
dfeec247 633 assert_eq!(to_string(f, -3.14, Minus, (0, 0), true), "-3.14E0");
cdc7bbd5
XL
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");
dfeec247
XL
636
637 assert_eq!(to_string(f, 0.1, Minus, (-4, 16), false), "0.1");
cdc7bbd5 638 assert_eq!(to_string(f, 0.1, Minus, (-4, 16), false), "0.1");
dfeec247 639 assert_eq!(to_string(f, 0.1, MinusPlus, (-4, 16), false), "+0.1");
dfeec247 640 assert_eq!(to_string(f, -0.1, Minus, (-4, 16), false), "-0.1");
dfeec247 641 assert_eq!(to_string(f, -0.1, MinusPlus, (-4, 16), false), "-0.1");
dfeec247 642 assert_eq!(to_string(f, 0.1, Minus, (0, 0), true), "1E-1");
cdc7bbd5
XL
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");
dfeec247 645 assert_eq!(to_string(f, -0.1, Minus, (0, 0), true), "-1E-1");
cdc7bbd5
XL
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");
dfeec247
XL
648
649 assert_eq!(to_string(f, 7.5e-11, Minus, (-4, 16), false), "7.5e-11");
d9579d0f
AL
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
dfeec247 653 assert_eq!(to_string(f, 1.9971e20, Minus, (-4, 16), false), "1.9971e20");
d9579d0f
AL
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
dfeec247 662 assert_eq!(to_string(f, f32::MAX, Minus, (-4, 16), false), "3.4028235e38");
d9579d0f
AL
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
3157f602 666 let minf32 = ldexp_f32(1.0, -149);
dfeec247 667 assert_eq!(to_string(f, minf32, Minus, (-4, 16), false), "1e-45");
d9579d0f
AL
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
dfeec247
XL
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");
d9579d0f 677
3157f602 678 let minf64 = ldexp_f64(1.0, -1074);
dfeec247 679 assert_eq!(to_string(f, minf64, Minus, (-4, 16), false), "5e-324");
d9579d0f
AL
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
686pub fn to_exact_exp_str_test<F>(mut f_: F)
dfeec247 687where
1b1a35ee 688 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
dfeec247 689{
d9579d0f
AL
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
dfeec247
XL
693 where
694 T: DecodableFloat,
1b1a35ee 695 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
dfeec247
XL
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 })
d9579d0f
AL
700 }
701
702 let f = &mut f_;
703
dfeec247 704 assert_eq!(to_string(f, 0.0, Minus, 1, true), "0E0");
cdc7bbd5
XL
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");
dfeec247 709 assert_eq!(to_string(f, 0.0, Minus, 2, true), "0.0E0");
cdc7bbd5
XL
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");
d9579d0f 714
dfeec247 715 assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1, false), "inf");
cdc7bbd5
XL
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");
dfeec247 718 assert_eq!(to_string(f, 0.0 / 0.0, Minus, 8, false), "NaN");
cdc7bbd5
XL
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");
dfeec247 721 assert_eq!(to_string(f, -1.0 / 0.0, Minus, 64, false), "-inf");
cdc7bbd5
XL
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");
dfeec247
XL
724
725 assert_eq!(to_string(f, 3.14, Minus, 1, true), "3E0");
cdc7bbd5
XL
726 assert_eq!(to_string(f, 3.14, Minus, 1, false), "3e0");
727 assert_eq!(to_string(f, 3.14, MinusPlus, 1, false), "+3e0");
dfeec247 728 assert_eq!(to_string(f, -3.14, Minus, 2, true), "-3.1E0");
cdc7bbd5
XL
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");
dfeec247 731 assert_eq!(to_string(f, 3.14, Minus, 3, true), "3.14E0");
cdc7bbd5
XL
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");
dfeec247 734 assert_eq!(to_string(f, -3.14, Minus, 4, true), "-3.140E0");
cdc7bbd5
XL
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");
d9579d0f 737
dfeec247 738 assert_eq!(to_string(f, 0.195, Minus, 1, false), "2e-1");
cdc7bbd5
XL
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");
dfeec247 741 assert_eq!(to_string(f, -0.195, Minus, 2, false), "-2.0e-1");
cdc7bbd5
XL
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");
dfeec247 744 assert_eq!(to_string(f, 0.195, Minus, 3, false), "1.95e-1");
cdc7bbd5
XL
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");
dfeec247 747 assert_eq!(to_string(f, -0.195, Minus, 4, false), "-1.950e-1");
cdc7bbd5
XL
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");
dfeec247
XL
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");
d9579d0f
AL
754 assert_eq!(to_string(f, 9.5, Minus, 30, false), "9.50000000000000000000000000000e0");
755
dfeec247
XL
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");
d9579d0f
AL
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
dfeec247
XL
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");
d9579d0f
AL
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");
dfeec247
XL
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");
d9579d0f
AL
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");
dfeec247
XL
804 assert_eq!(
805 to_string(f, f32::MAX, Minus, 64, false),
806 "3.402823466385288598117041834845169254400000000000000000000000000e38"
807 );
d9579d0f 808
3157f602 809 let minf32 = ldexp_f32(1.0, -149);
dfeec247
XL
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
416331ca
XL
828 return;
829 }
830
dfeec247
XL
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\
d9579d0f
AL
849 0315726078002853876058955863276687817154045895351438246423432132\
850 6889464182768467546703537516986049910576551282076245490090389328\
dfeec247
XL
851 9440758685084551339423045832369032229481658085593321233482747978e308"
852 );
853 assert_eq!(
854 to_string(f, f64::MAX, Minus, 512, false),
855 "1.797693134862315708145274237317043567980705675258449965989174768\
d9579d0f
AL
856 0315726078002853876058955863276687817154045895351438246423432132\
857 6889464182768467546703537516986049910576551282076245490090389328\
858 9440758685084551339423045832369032229481658085593321233482747978\
859 2620414472316873817718091929988125040402618412485836800000000000\
860 0000000000000000000000000000000000000000000000000000000000000000\
861 0000000000000000000000000000000000000000000000000000000000000000\
dfeec247
XL
862 0000000000000000000000000000000000000000000000000000000000000000e308"
863 );
d9579d0f
AL
864
865 // okay, this is becoming tough. fortunately for us, this is almost the worst case.
3157f602 866 let minf64 = ldexp_f64(1.0, -1074);
dfeec247
XL
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\
d9579d0f
AL
885 0067550727020875186529983636163599237979656469544571773092665671\
886 0355939796398774796010781878126300713190311404527845817167848982\
dfeec247
XL
887 1036887186360569987307230500063874091535649843873124733972731696e-324"
888 );
889 assert_eq!(
890 to_string(f, minf64, Minus, 512, false),
891 "4.940656458412465441765687928682213723650598026143247644255856825\
d9579d0f
AL
892 0067550727020875186529983636163599237979656469544571773092665671\
893 0355939796398774796010781878126300713190311404527845817167848982\
894 1036887186360569987307230500063874091535649843873124733972731696\
895 1514003171538539807412623856559117102665855668676818703956031062\
896 4931945271591492455329305456544401127480129709999541931989409080\
897 4165633245247571478690147267801593552386115501348035264934720193\
dfeec247
XL
898 7902681071074917033322268447533357208324319360923828934583680601e-324"
899 );
900 assert_eq!(
901 to_string(f, minf64, Minus, 1024, false),
902 "4.940656458412465441765687928682213723650598026143247644255856825\
d9579d0f
AL
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\
dfeec247
XL
917 0000000000000000000000000000000000000000000000000000000000000000e-324"
918 );
d9579d0f
AL
919
920 // very large output
dfeec247
XL
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 );
d9579d0f
AL
940}
941
942pub fn to_exact_fixed_str_test<F>(mut f_: F)
dfeec247 943where
1b1a35ee 944 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
dfeec247 945{
d9579d0f
AL
946 use core::num::flt2dec::Sign::*;
947
74b04a01 948 fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
dfeec247
XL
949 where
950 T: DecodableFloat,
1b1a35ee 951 F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
dfeec247
XL
952 {
953 to_string_with_parts(|buf, parts| {
74b04a01 954 to_exact_fixed_str(|d, b, l| f(d, b, l), v, sign, frac_digits, buf, parts)
dfeec247 955 })
d9579d0f
AL
956 }
957
958 let f = &mut f_;
959
74b04a01 960 assert_eq!(to_string(f, 0.0, Minus, 0), "0");
74b04a01 961 assert_eq!(to_string(f, 0.0, MinusPlus, 0), "+0");
cdc7bbd5
XL
962 assert_eq!(to_string(f, -0.0, Minus, 0), "-0");
963 assert_eq!(to_string(f, -0.0, MinusPlus, 0), "-0");
74b04a01 964 assert_eq!(to_string(f, 0.0, Minus, 1), "0.0");
74b04a01 965 assert_eq!(to_string(f, 0.0, MinusPlus, 1), "+0.0");
cdc7bbd5
XL
966 assert_eq!(to_string(f, -0.0, Minus, 8), "-0.00000000");
967 assert_eq!(to_string(f, -0.0, MinusPlus, 8), "-0.00000000");
74b04a01
XL
968
969 assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf");
cdc7bbd5
XL
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");
74b04a01 972 assert_eq!(to_string(f, 0.0 / 0.0, Minus, 0), "NaN");
cdc7bbd5
XL
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");
74b04a01 975 assert_eq!(to_string(f, -1.0 / 0.0, Minus, 0), "-inf");
cdc7bbd5
XL
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");
74b04a01
XL
978
979 assert_eq!(to_string(f, 3.14, Minus, 0), "3");
cdc7bbd5 980 assert_eq!(to_string(f, 3.14, Minus, 0), "3");
74b04a01 981 assert_eq!(to_string(f, 3.14, MinusPlus, 0), "+3");
74b04a01 982 assert_eq!(to_string(f, -3.14, Minus, 0), "-3");
cdc7bbd5 983 assert_eq!(to_string(f, -3.14, Minus, 0), "-3");
74b04a01 984 assert_eq!(to_string(f, -3.14, MinusPlus, 0), "-3");
74b04a01 985 assert_eq!(to_string(f, 3.14, Minus, 1), "3.1");
cdc7bbd5
XL
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");
74b04a01 989 assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000");
74b04a01 990 assert_eq!(to_string(f, -3.14, MinusPlus, 8), "-3.14000000");
74b04a01
XL
991
992 assert_eq!(to_string(f, 0.195, Minus, 0), "0");
74b04a01 993 assert_eq!(to_string(f, 0.195, MinusPlus, 0), "+0");
74b04a01 994 assert_eq!(to_string(f, -0.195, Minus, 0), "-0");
cdc7bbd5 995 assert_eq!(to_string(f, -0.195, Minus, 0), "-0");
74b04a01 996 assert_eq!(to_string(f, -0.195, MinusPlus, 0), "-0");
74b04a01 997 assert_eq!(to_string(f, 0.195, Minus, 1), "0.2");
cdc7bbd5
XL
998 assert_eq!(to_string(f, 0.195, Minus, 2), "0.20");
999 assert_eq!(to_string(f, 0.195, MinusPlus, 4), "+0.1950");
74b04a01 1000 assert_eq!(to_string(f, -0.195, Minus, 5), "-0.19500");
cdc7bbd5
XL
1001 assert_eq!(to_string(f, -0.195, Minus, 6), "-0.195000");
1002 assert_eq!(to_string(f, -0.195, MinusPlus, 8), "-0.19500000");
74b04a01
XL
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");
dfeec247 1063 assert_eq!(
74b04a01 1064 to_string(f, 1.0e-6, Minus, 55),
dfeec247
XL
1065 "0.0000009999999999999999547481118258862586856139387236908"
1066 );
1067 assert_eq!(
74b04a01 1068 to_string(f, 1.0e-6, Minus, 65),
dfeec247
XL
1069 "0.00000099999999999999995474811182588625868561393872369080781936646"
1070 );
1071 assert_eq!(
74b04a01 1072 to_string(f, 1.0e-6, Minus, 75),
dfeec247
XL
1073 "0.000000999999999999999954748111825886258685613938723690807819366455078125000"
1074 );
1075
74b04a01
XL
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");
dfeec247
XL
1079
1080 if cfg!(miri) {
1081 // Miri is too slow
416331ca
XL
1082 return;
1083 }
1084
3157f602 1085 let minf32 = ldexp_f32(1.0, -149);
74b04a01
XL
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");
dfeec247 1093 assert_eq!(
74b04a01 1094 to_string(f, minf32, Minus, 64),
dfeec247
XL
1095 "0.0000000000000000000000000000000000000000000014012984643248170709"
1096 );
1097 assert_eq!(
74b04a01 1098 to_string(f, minf32, Minus, 128),
dfeec247
XL
1099 "0.0000000000000000000000000000000000000000000014012984643248170709\
1100 2372958328991613128026194187651577175706828388979108268586060149"
1101 );
1102 assert_eq!(
74b04a01 1103 to_string(f, minf32, Minus, 256),
dfeec247 1104 "0.0000000000000000000000000000000000000000000014012984643248170709\
d9579d0f
AL
1105 2372958328991613128026194187651577175706828388979108268586060148\
1106 6638188362121582031250000000000000000000000000000000000000000000\
dfeec247
XL
1107 0000000000000000000000000000000000000000000000000000000000000000"
1108 );
d9579d0f 1109
dfeec247 1110 assert_eq!(
74b04a01 1111 to_string(f, f64::MAX, Minus, 0),
dfeec247 1112 "1797693134862315708145274237317043567980705675258449965989174768\
d9579d0f
AL
1113 0315726078002853876058955863276687817154045895351438246423432132\
1114 6889464182768467546703537516986049910576551282076245490090389328\
1115 9440758685084551339423045832369032229481658085593321233482747978\
dfeec247
XL
1116 26204144723168738177180919299881250404026184124858368"
1117 );
1118 assert_eq!(
74b04a01 1119 to_string(f, f64::MAX, Minus, 10),
dfeec247 1120 "1797693134862315708145274237317043567980705675258449965989174768\
d9579d0f
AL
1121 0315726078002853876058955863276687817154045895351438246423432132\
1122 6889464182768467546703537516986049910576551282076245490090389328\
1123 9440758685084551339423045832369032229481658085593321233482747978\
dfeec247
XL
1124 26204144723168738177180919299881250404026184124858368.0000000000"
1125 );
d9579d0f 1126
3157f602 1127 let minf64 = ldexp_f64(1.0, -1074);
74b04a01
XL
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");
dfeec247 1131 assert_eq!(
74b04a01 1132 to_string(f, minf64, Minus, 100),
dfeec247
XL
1133 "0.0000000000000000000000000000000000000000000000000000000000000000\
1134 000000000000000000000000000000000000"
1135 );
1136 assert_eq!(
74b04a01 1137 to_string(f, minf64, Minus, 1000),
dfeec247 1138 "0.0000000000000000000000000000000000000000000000000000000000000000\
d9579d0f
AL
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\
dfeec247
XL
1153 1014510378627381672509558373897335989937"
1154 );
d9579d0f
AL
1155
1156 // very large output
74b04a01
XL
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}", ""));
dfeec247 1160 assert_eq!(
74b04a01 1161 to_string(f, 1.0e-1, Minus, 80000),
dfeec247
XL
1162 format!("0.1000000000000000055511151231257827021181583404541015625{:0>79945}", "")
1163 );
1164 assert_eq!(
74b04a01 1165 to_string(f, 1.0e-20, Minus, 80000),
dfeec247
XL
1166 format!(
1167 "0.0000000000000000000099999999999999994515327145420957165172950370\
1168 2787392447107715776066783064379706047475337982177734375{:0>79881}",
1169 ""
1170 )
1171 );
d9579d0f 1172}