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