]> git.proxmox.com Git - rustc.git/blame - src/libcore/num/flt2dec/mod.rs
New upstream version 1.44.1+dfsg1
[rustc.git] / src / libcore / num / flt2dec / mod.rs
CommitLineData
d9579d0f
AL
1/*!
2
3Floating-point number to decimal conversion routines.
4
5# Problem statement
6
7We are given the floating-point number `v = f * 2^e` with an integer `f`,
8and its bounds `minus` and `plus` such that any number between `v - minus` and
9`v + plus` will be rounded to `v`. For the simplicity we assume that
10this range is exclusive. Then we would like to get the unique decimal
11representation `V = 0.d[0..n-1] * 10^k` such that:
12
13- `d[0]` is non-zero.
14
15- It's correctly rounded when parsed back: `v - minus < V < v + plus`.
0731742a 16 Furthermore it is shortest such one, i.e., there is no representation
d9579d0f
AL
17 with less than `n` digits that is correctly rounded.
18
19- It's closest to the original value: `abs(V - v) <= 10^(k-n) / 2`. Note that
20 there might be two representations satisfying this uniqueness requirement,
21 in which case some tie-breaking mechanism is used.
22
23We will call this mode of operation as to the *shortest* mode. This mode is used
24when there is no additional constraint, and can be thought as a "natural" mode
25as it matches the ordinary intuition (it at least prints `0.1f32` as "0.1").
26
27We have two more modes of operation closely related to each other. In these modes
28we are given either the number of significant digits `n` or the last-digit
29limitation `limit` (which determines the actual `n`), and we would like to get
30the representation `V = 0.d[0..n-1] * 10^k` such that:
31
32- `d[0]` is non-zero, unless `n` was zero in which case only `k` is returned.
33
34- It's closest to the original value: `abs(V - v) <= 10^(k-n) / 2`. Again,
35 there might be some tie-breaking mechanism.
36
37When `limit` is given but not `n`, we set `n` such that `k - n = limit`
38so that the last digit `d[n-1]` is scaled by `10^(k-n) = 10^limit`.
39If such `n` is negative, we clip it to zero so that we will only get `k`.
40We are also limited by the supplied buffer. This limitation is used to print
41the number up to given number of fractional digits without knowing
42the correct `k` beforehand.
43
44We will call the mode of operation requiring `n` as to the *exact* mode,
45and one requiring `limit` as to the *fixed* mode. The exact mode is a subset of
46the fixed mode: the sufficiently large last-digit limitation will eventually fill
47the supplied buffer and let the algorithm to return.
48
49# Implementation overview
50
51It is easy to get the floating point printing correct but slow (Russ Cox has
52[demonstrated](http://research.swtch.com/ftoa) how it's easy), or incorrect but
53fast (naïve division and modulo). But it is surprisingly hard to print
54floating point numbers correctly *and* efficiently.
55
56There are two classes of algorithms widely known to be correct.
57
58- The "Dragon" family of algorithm is first described by Guy L. Steele Jr. and
59 Jon L. White. They rely on the fixed-size big integer for their correctness.
60 A slight improvement was found later, which is posthumously described by
61 Robert G. Burger and R. Kent Dybvig. David Gay's `dtoa.c` routine is
62 a popular implementation of this strategy.
63
64- The "Grisu" family of algorithm is first described by Florian Loitsch.
65 They use very cheap integer-only procedure to determine the close-to-correct
66 representation which is at least guaranteed to be shortest. The variant,
67 Grisu3, actively detects if the resulting representation is incorrect.
68
69We implement both algorithms with necessary tweaks to suit our requirements.
70In particular, published literatures are short of the actual implementation
71difficulties like how to avoid arithmetic overflows. Each implementation,
72available in `strategy::dragon` and `strategy::grisu` respectively,
73extensively describes all necessary justifications and many proofs for them.
74(It is still difficult to follow though. You have been warned.)
75
76Both implementations expose two public functions:
77
78- `format_shortest(decoded, buf)`, which always needs at least
79 `MAX_SIG_DIGITS` digits of buffer. Implements the shortest mode.
80
81- `format_exact(decoded, buf, limit)`, which accepts as small as
82 one digit of buffer. Implements exact and fixed modes.
83
84They try to fill the `u8` buffer with digits and returns the number of digits
85written and the exponent `k`. They are total for all finite `f32` and `f64`
86inputs (Grisu internally falls back to Dragon if necessary).
87
88The rendered digits are formatted into the actual string form with
89four functions:
90
91- `to_shortest_str` prints the shortest representation, which can be padded by
92 zeroes to make *at least* given number of fractional digits.
93
94- `to_shortest_exp_str` prints the shortest representation, which can be
95 padded by zeroes when its exponent is in the specified ranges,
96 or can be printed in the exponential form such as `1.23e45`.
97
98- `to_exact_exp_str` prints the exact representation with given number of
99 digits in the exponential form.
100
101- `to_exact_fixed_str` prints the fixed representation with *exactly*
102 given number of fractional digits.
103
104They all return a slice of preallocated `Part` array, which corresponds to
105the individual part of strings: a fixed string, a part of rendered digits,
106a number of zeroes or a small (`u16`) number. The caller is expected to
107provide a large enough buffer and `Part` array, and to assemble the final
108string from resulting `Part`s itself.
109
110All algorithms and formatting functions are accompanied by extensive tests
cc61c64b 111in `coretests::num::flt2dec` module. It also shows how to use individual
d9579d0f
AL
112functions.
113
114*/
115
116// while this is extensively documented, this is in principle private which is
117// only made public for testing. do not expose us.
118#![doc(hidden)]
60c5eb7d
XL
119#![unstable(
120 feature = "flt2dec",
121 reason = "internal routines only exposed for testing",
dfeec247 122 issue = "none"
60c5eb7d 123)]
d9579d0f 124
60c5eb7d 125pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded};
48663c56 126use crate::i16;
d9579d0f 127
d9579d0f 128pub mod decoder;
60c5eb7d 129pub mod estimator;
d9579d0f
AL
130
131/// Digit-generation algorithms.
132pub mod strategy {
133 pub mod dragon;
134 pub mod grisu;
135}
136
137/// The minimum size of buffer necessary for the shortest mode.
138///
139/// It is a bit non-trivial to derive, but this is one plus the maximal number of
140/// significant decimal digits from formatting algorithms with the shortest result.
141/// The exact formula is `ceil(# bits in mantissa * log_10 2 + 1)`.
142pub const MAX_SIG_DIGITS: usize = 17;
143
144/// When `d[..n]` contains decimal digits, increase the last digit and propagate carry.
145/// Returns a next digit when it causes the length change.
146#[doc(hidden)]
147pub fn round_up(d: &mut [u8], n: usize) -> Option<u8> {
148 match d[..n].iter().rposition(|&c| c != b'9') {
60c5eb7d
XL
149 Some(i) => {
150 // d[i+1..n] is all nines
d9579d0f 151 d[i] += 1;
60c5eb7d
XL
152 for j in i + 1..n {
153 d[j] = b'0';
154 }
d9579d0f
AL
155 None
156 }
60c5eb7d
XL
157 None if n > 0 => {
158 // 999..999 rounds to 1000..000 with an increased exponent
d9579d0f 159 d[0] = b'1';
60c5eb7d
XL
160 for j in 1..n {
161 d[j] = b'0';
162 }
d9579d0f
AL
163 Some(b'0')
164 }
60c5eb7d
XL
165 None => {
166 // an empty buffer rounds up (a bit strange but reasonable)
d9579d0f
AL
167 Some(b'1')
168 }
169 }
170}
171
172/// Formatted parts.
173#[derive(Copy, Clone, PartialEq, Eq, Debug)]
174pub enum Part<'a> {
175 /// Given number of zero digits.
176 Zero(usize),
177 /// A literal number up to 5 digits.
178 Num(u16),
179 /// A verbatim copy of given bytes.
180 Copy(&'a [u8]),
181}
182
183impl<'a> Part<'a> {
184 /// Returns the exact byte length of given part.
185 pub fn len(&self) -> usize {
186 match *self {
187 Part::Zero(nzeroes) => nzeroes,
60c5eb7d
XL
188 Part::Num(v) => {
189 if v < 1_000 {
190 if v < 10 {
191 1
192 } else if v < 100 {
193 2
194 } else {
195 3
196 }
197 } else {
198 if v < 10_000 { 4 } else { 5 }
199 }
200 }
d9579d0f
AL
201 Part::Copy(buf) => buf.len(),
202 }
203 }
204
205 /// Writes a part into the supplied buffer.
206 /// Returns the number of written bytes, or `None` if the buffer is not enough.
207 /// (It may still leave partially written bytes in the buffer; do not rely on that.)
208 pub fn write(&self, out: &mut [u8]) -> Option<usize> {
209 let len = self.len();
210 if out.len() >= len {
211 match *self {
212 Part::Zero(nzeroes) => {
60c5eb7d
XL
213 for c in &mut out[..nzeroes] {
214 *c = b'0';
215 }
d9579d0f
AL
216 }
217 Part::Num(mut v) => {
218 for c in out[..len].iter_mut().rev() {
219 *c = b'0' + (v % 10) as u8;
220 v /= 10;
221 }
222 }
223 Part::Copy(buf) => {
7453a54e 224 out[..buf.len()].copy_from_slice(buf);
d9579d0f
AL
225 }
226 }
227 Some(len)
228 } else {
229 None
230 }
231 }
232}
233
234/// Formatted result containing one or more parts.
235/// This can be written to the byte buffer or converted to the allocated string.
54a0048b 236#[allow(missing_debug_implementations)]
d9579d0f
AL
237#[derive(Clone)]
238pub struct Formatted<'a> {
239 /// A byte slice representing a sign, either `""`, `"-"` or `"+"`.
74b04a01 240 pub sign: &'static str,
d9579d0f
AL
241 /// Formatted parts to be rendered after a sign and optional zero padding.
242 pub parts: &'a [Part<'a>],
243}
244
245impl<'a> Formatted<'a> {
246 /// Returns the exact byte length of combined formatted result.
247 pub fn len(&self) -> usize {
248 let mut len = self.sign.len();
249 for part in self.parts {
250 len += part.len();
251 }
252 len
253 }
254
255 /// Writes all formatted parts into the supplied buffer.
256 /// Returns the number of written bytes, or `None` if the buffer is not enough.
257 /// (It may still leave partially written bytes in the buffer; do not rely on that.)
258 pub fn write(&self, out: &mut [u8]) -> Option<usize> {
60c5eb7d
XL
259 if out.len() < self.sign.len() {
260 return None;
261 }
74b04a01 262 out[..self.sign.len()].copy_from_slice(self.sign.as_bytes());
d9579d0f
AL
263
264 let mut written = self.sign.len();
265 for part in self.parts {
532ac7d7
XL
266 let len = part.write(&mut out[written..])?;
267 written += len;
d9579d0f
AL
268 }
269 Some(written)
270 }
271}
272
273/// Formats given decimal digits `0.<...buf...> * 10^exp` into the decimal form
274/// with at least given number of fractional digits. The result is stored to
275/// the supplied parts array and a slice of written parts is returned.
276///
277/// `frac_digits` can be less than the number of actual fractional digits in `buf`;
278/// it will be ignored and full digits will be printed. It is only used to print
279/// additional zeroes after rendered digits. Thus `frac_digits` of 0 means that
280/// it will only print given digits and nothing else.
60c5eb7d
XL
281fn digits_to_dec_str<'a>(
282 buf: &'a [u8],
283 exp: i16,
284 frac_digits: usize,
285 parts: &'a mut [Part<'a>],
286) -> &'a [Part<'a>] {
d9579d0f
AL
287 assert!(!buf.is_empty());
288 assert!(buf[0] > b'0');
289 assert!(parts.len() >= 4);
290
291 // if there is the restriction on the last digit position, `buf` is assumed to be
292 // left-padded with the virtual zeroes. the number of virtual zeroes, `nzeroes`,
293 // equals to `max(0, exp + frac_digits - buf.len())`, so that the position of
294 // the last digit `exp - buf.len() - nzeroes` is no more than `-frac_digits`:
295 //
296 // |<-virtual->|
297 // |<---- buf ---->| zeroes | exp
298 // 0. 1 2 3 4 5 6 7 8 9 _ _ _ _ _ _ x 10
299 // | | |
300 // 10^exp 10^(exp-buf.len()) 10^(exp-buf.len()-nzeroes)
301 //
302 // `nzeroes` is individually calculated for each case in order to avoid overflow.
303
304 if exp <= 0 {
305 // the decimal point is before rendered digits: [0.][000...000][1234][____]
306 let minus_exp = -(exp as i32) as usize;
307 parts[0] = Part::Copy(b"0.");
308 parts[1] = Part::Zero(minus_exp);
309 parts[2] = Part::Copy(buf);
310 if frac_digits > buf.len() && frac_digits - buf.len() > minus_exp {
311 parts[3] = Part::Zero((frac_digits - buf.len()) - minus_exp);
312 &parts[..4]
313 } else {
314 &parts[..3]
315 }
316 } else {
317 let exp = exp as usize;
318 if exp < buf.len() {
319 // the decimal point is inside rendered digits: [12][.][34][____]
320 parts[0] = Part::Copy(&buf[..exp]);
321 parts[1] = Part::Copy(b".");
322 parts[2] = Part::Copy(&buf[exp..]);
323 if frac_digits > buf.len() - exp {
324 parts[3] = Part::Zero(frac_digits - (buf.len() - exp));
325 &parts[..4]
326 } else {
327 &parts[..3]
328 }
329 } else {
330 // the decimal point is after rendered digits: [1234][____0000] or [1234][__][.][__].
331 parts[0] = Part::Copy(buf);
332 parts[1] = Part::Zero(exp - buf.len());
333 if frac_digits > 0 {
334 parts[2] = Part::Copy(b".");
335 parts[3] = Part::Zero(frac_digits);
336 &parts[..4]
337 } else {
338 &parts[..2]
339 }
340 }
341 }
342}
343
532ac7d7
XL
344/// Formats the given decimal digits `0.<...buf...> * 10^exp` into the exponential
345/// form with at least the given number of significant digits. When `upper` is `true`,
d9579d0f
AL
346/// the exponent will be prefixed by `E`; otherwise that's `e`. The result is
347/// stored to the supplied parts array and a slice of written parts is returned.
348///
349/// `min_digits` can be less than the number of actual significant digits in `buf`;
350/// it will be ignored and full digits will be printed. It is only used to print
532ac7d7
XL
351/// additional zeroes after rendered digits. Thus, `min_digits == 0` means that
352/// it will only print the given digits and nothing else.
60c5eb7d
XL
353fn digits_to_exp_str<'a>(
354 buf: &'a [u8],
355 exp: i16,
356 min_ndigits: usize,
357 upper: bool,
358 parts: &'a mut [Part<'a>],
359) -> &'a [Part<'a>] {
d9579d0f
AL
360 assert!(!buf.is_empty());
361 assert!(buf[0] > b'0');
362 assert!(parts.len() >= 6);
363
364 let mut n = 0;
365
366 parts[n] = Part::Copy(&buf[..1]);
367 n += 1;
368
369 if buf.len() > 1 || min_ndigits > 1 {
370 parts[n] = Part::Copy(b".");
371 parts[n + 1] = Part::Copy(&buf[1..]);
372 n += 2;
373 if min_ndigits > buf.len() {
374 parts[n] = Part::Zero(min_ndigits - buf.len());
375 n += 1;
376 }
377 }
378
379 // 0.1234 x 10^exp = 1.234 x 10^(exp-1)
380 let exp = exp as i32 - 1; // avoid underflow when exp is i16::MIN
381 if exp < 0 {
382 parts[n] = Part::Copy(if upper { b"E-" } else { b"e-" });
383 parts[n + 1] = Part::Num(-exp as u16);
384 } else {
385 parts[n] = Part::Copy(if upper { b"E" } else { b"e" });
386 parts[n + 1] = Part::Num(exp as u16);
387 }
388 &parts[..n + 2]
389}
390
391/// Sign formatting options.
392#[derive(Copy, Clone, PartialEq, Eq, Debug)]
393pub enum Sign {
394 /// Prints `-` only for the negative non-zero values.
60c5eb7d 395 Minus, // -inf -1 0 0 1 inf nan
d9579d0f 396 /// Prints `-` only for any negative values (including the negative zero).
60c5eb7d 397 MinusRaw, // -inf -1 -0 0 1 inf nan
d9579d0f 398 /// Prints `-` for the negative non-zero values, or `+` otherwise.
60c5eb7d 399 MinusPlus, // -inf -1 +0 +0 +1 +inf nan
d9579d0f
AL
400 /// Prints `-` for any negative values (including the negative zero), or `+` otherwise.
401 MinusPlusRaw, // -inf -1 -0 +0 +1 +inf nan
402}
403
404/// Returns the static byte string corresponding to the sign to be formatted.
74b04a01
XL
405/// It can be either `""`, `"+"` or `"-"`.
406fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static str {
d9579d0f 407 match (*decoded, sign) {
74b04a01
XL
408 (FullDecoded::Nan, _) => "",
409 (FullDecoded::Zero, Sign::Minus) => "",
60c5eb7d
XL
410 (FullDecoded::Zero, Sign::MinusRaw) => {
411 if negative {
74b04a01 412 "-"
60c5eb7d 413 } else {
74b04a01 414 ""
60c5eb7d
XL
415 }
416 }
74b04a01 417 (FullDecoded::Zero, Sign::MinusPlus) => "+",
60c5eb7d
XL
418 (FullDecoded::Zero, Sign::MinusPlusRaw) => {
419 if negative {
74b04a01 420 "-"
60c5eb7d 421 } else {
74b04a01 422 "+"
60c5eb7d
XL
423 }
424 }
ba9703b0 425 (_, Sign::Minus | Sign::MinusRaw) => {
60c5eb7d 426 if negative {
74b04a01 427 "-"
60c5eb7d 428 } else {
74b04a01 429 ""
60c5eb7d
XL
430 }
431 }
ba9703b0 432 (_, Sign::MinusPlus | Sign::MinusPlusRaw) => {
60c5eb7d 433 if negative {
74b04a01 434 "-"
60c5eb7d 435 } else {
74b04a01 436 "+"
60c5eb7d
XL
437 }
438 }
d9579d0f
AL
439 }
440}
441
532ac7d7 442/// Formats the given floating point number into the decimal form with at least
d9579d0f
AL
443/// given number of fractional digits. The result is stored to the supplied parts
444/// array while utilizing given byte buffer as a scratch. `upper` is currently
445/// unused but left for the future decision to change the case of non-finite values,
0731742a 446/// i.e., `inf` and `nan`. The first part to be rendered is always a `Part::Sign`
d9579d0f
AL
447/// (which can be an empty string if no sign is rendered).
448///
449/// `format_shortest` should be the underlying digit-generation function.
450/// You probably would want `strategy::grisu::format_shortest` for this.
451///
452/// `frac_digits` can be less than the number of actual fractional digits in `v`;
453/// it will be ignored and full digits will be printed. It is only used to print
454/// additional zeroes after rendered digits. Thus `frac_digits` of 0 means that
455/// it will only print given digits and nothing else.
456///
457/// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long.
7cac9316
XL
458/// There should be at least 4 parts available, due to the worst case like
459/// `[+][0.][0000][2][0000]` with `frac_digits = 10`.
60c5eb7d
XL
460pub fn to_shortest_str<'a, T, F>(
461 mut format_shortest: F,
462 v: T,
463 sign: Sign,
464 frac_digits: usize,
60c5eb7d
XL
465 buf: &'a mut [u8],
466 parts: &'a mut [Part<'a>],
467) -> Formatted<'a>
468where
469 T: DecodableFloat,
470 F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
471{
d9579d0f
AL
472 assert!(parts.len() >= 4);
473 assert!(buf.len() >= MAX_SIG_DIGITS);
474
475 let (negative, full_decoded) = decode(v);
476 let sign = determine_sign(sign, &full_decoded, negative);
477 match full_decoded {
478 FullDecoded::Nan => {
479 parts[0] = Part::Copy(b"NaN");
b7449926 480 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
481 }
482 FullDecoded::Infinite => {
483 parts[0] = Part::Copy(b"inf");
b7449926 484 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
485 }
486 FullDecoded::Zero => {
60c5eb7d
XL
487 if frac_digits > 0 {
488 // [0.][0000]
d9579d0f
AL
489 parts[0] = Part::Copy(b"0.");
490 parts[1] = Part::Zero(frac_digits);
b7449926 491 Formatted { sign, parts: &parts[..2] }
d9579d0f
AL
492 } else {
493 parts[0] = Part::Copy(b"0");
b7449926 494 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
495 }
496 }
497 FullDecoded::Finite(ref decoded) => {
498 let (len, exp) = format_shortest(decoded, buf);
60c5eb7d 499 Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
d9579d0f
AL
500 }
501 }
502}
503
532ac7d7 504/// Formats the given floating point number into the decimal form or
d9579d0f
AL
505/// the exponential form, depending on the resulting exponent. The result is
506/// stored to the supplied parts array while utilizing given byte buffer
507/// as a scratch. `upper` is used to determine the case of non-finite values
508/// (`inf` and `nan`) or the case of the exponent prefix (`e` or `E`).
509/// The first part to be rendered is always a `Part::Sign` (which can be
510/// an empty string if no sign is rendered).
511///
512/// `format_shortest` should be the underlying digit-generation function.
513/// You probably would want `strategy::grisu::format_shortest` for this.
514///
515/// The `dec_bounds` is a tuple `(lo, hi)` such that the number is formatted
b039eaaf 516/// as decimal only when `10^lo <= V < 10^hi`. Note that this is the *apparent* `V`
d9579d0f
AL
517/// instead of the actual `v`! Thus any printed exponent in the exponential form
518/// cannot be in this range, avoiding any confusion.
519///
520/// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long.
7cac9316
XL
521/// There should be at least 6 parts available, due to the worst case like
522/// `[+][1][.][2345][e][-][6]`.
60c5eb7d
XL
523pub fn to_shortest_exp_str<'a, T, F>(
524 mut format_shortest: F,
525 v: T,
526 sign: Sign,
527 dec_bounds: (i16, i16),
528 upper: bool,
529 buf: &'a mut [u8],
530 parts: &'a mut [Part<'a>],
531) -> Formatted<'a>
532where
533 T: DecodableFloat,
534 F: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
535{
d9579d0f
AL
536 assert!(parts.len() >= 6);
537 assert!(buf.len() >= MAX_SIG_DIGITS);
538 assert!(dec_bounds.0 <= dec_bounds.1);
539
540 let (negative, full_decoded) = decode(v);
541 let sign = determine_sign(sign, &full_decoded, negative);
542 match full_decoded {
543 FullDecoded::Nan => {
544 parts[0] = Part::Copy(b"NaN");
b7449926 545 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
546 }
547 FullDecoded::Infinite => {
548 parts[0] = Part::Copy(b"inf");
b7449926 549 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
550 }
551 FullDecoded::Zero => {
552 parts[0] = if dec_bounds.0 <= 0 && 0 < dec_bounds.1 {
553 Part::Copy(b"0")
554 } else {
555 Part::Copy(if upper { b"0E0" } else { b"0e0" })
556 };
b7449926 557 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
558 }
559 FullDecoded::Finite(ref decoded) => {
560 let (len, exp) = format_shortest(decoded, buf);
561 let vis_exp = exp as i32 - 1;
562 let parts = if dec_bounds.0 as i32 <= vis_exp && vis_exp < dec_bounds.1 as i32 {
563 digits_to_dec_str(&buf[..len], exp, 0, parts)
564 } else {
565 digits_to_exp_str(&buf[..len], exp, 0, upper, parts)
566 };
b7449926 567 Formatted { sign, parts }
d9579d0f
AL
568 }
569 }
570}
571
532ac7d7 572/// Returns a rather crude approximation (upper bound) for the maximum buffer size
d9579d0f
AL
573/// calculated from the given decoded exponent.
574///
575/// The exact limit is:
576///
577/// - when `exp < 0`, the maximum length is `ceil(log_10 (5^-exp * (2^64 - 1)))`.
578/// - when `exp >= 0`, the maximum length is `ceil(log_10 (2^exp * (2^64 - 1)))`.
579///
580/// `ceil(log_10 (x^exp * (2^64 - 1)))` is less than `ceil(log_10 (2^64 - 1)) +
581/// ceil(exp * log_10 x)`, which is in turn less than `20 + (1 + exp * log_10 x)`.
582/// We use the facts that `log_10 2 < 5/16` and `log_10 5 < 12/16`, which is
583/// enough for our purposes.
584///
585/// Why do we need this? `format_exact` functions will fill the entire buffer
586/// unless limited by the last digit restriction, but it is possible that
587/// the number of digits requested is ridiculously large (say, 30,000 digits).
588/// The vast majority of buffer will be filled with zeroes, so we don't want to
589/// allocate all the buffer beforehand. Consequently, for any given arguments,
590/// 826 bytes of buffer should be sufficient for `f64`. Compare this with
591/// the actual number for the worst case: 770 bytes (when `exp = -1074`).
592fn estimate_max_buf_len(exp: i16) -> usize {
593 21 + ((if exp < 0 { -12 } else { 5 } * exp as i32) as usize >> 4)
594}
595
596/// Formats given floating point number into the exponential form with
597/// exactly given number of significant digits. The result is stored to
598/// the supplied parts array while utilizing given byte buffer as a scratch.
599/// `upper` is used to determine the case of the exponent prefix (`e` or `E`).
600/// The first part to be rendered is always a `Part::Sign` (which can be
601/// an empty string if no sign is rendered).
602///
603/// `format_exact` should be the underlying digit-generation function.
604/// You probably would want `strategy::grisu::format_exact` for this.
605///
606/// The byte buffer should be at least `ndigits` bytes long unless `ndigits` is
607/// so large that only the fixed number of digits will be ever written.
608/// (The tipping point for `f64` is about 800, so 1000 bytes should be enough.)
7cac9316
XL
609/// There should be at least 6 parts available, due to the worst case like
610/// `[+][1][.][2345][e][-][6]`.
60c5eb7d
XL
611pub fn to_exact_exp_str<'a, T, F>(
612 mut format_exact: F,
613 v: T,
614 sign: Sign,
615 ndigits: usize,
616 upper: bool,
617 buf: &'a mut [u8],
618 parts: &'a mut [Part<'a>],
619) -> Formatted<'a>
620where
621 T: DecodableFloat,
622 F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
623{
d9579d0f
AL
624 assert!(parts.len() >= 6);
625 assert!(ndigits > 0);
626
627 let (negative, full_decoded) = decode(v);
628 let sign = determine_sign(sign, &full_decoded, negative);
629 match full_decoded {
630 FullDecoded::Nan => {
631 parts[0] = Part::Copy(b"NaN");
b7449926 632 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
633 }
634 FullDecoded::Infinite => {
635 parts[0] = Part::Copy(b"inf");
b7449926 636 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
637 }
638 FullDecoded::Zero => {
60c5eb7d
XL
639 if ndigits > 1 {
640 // [0.][0000][e0]
d9579d0f
AL
641 parts[0] = Part::Copy(b"0.");
642 parts[1] = Part::Zero(ndigits - 1);
643 parts[2] = Part::Copy(if upper { b"E0" } else { b"e0" });
b7449926 644 Formatted { sign, parts: &parts[..3] }
d9579d0f
AL
645 } else {
646 parts[0] = Part::Copy(if upper { b"0E0" } else { b"0e0" });
b7449926 647 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
648 }
649 }
650 FullDecoded::Finite(ref decoded) => {
651 let maxlen = estimate_max_buf_len(decoded.exp);
652 assert!(buf.len() >= ndigits || buf.len() >= maxlen);
653
654 let trunc = if ndigits < maxlen { ndigits } else { maxlen };
655 let (len, exp) = format_exact(decoded, &mut buf[..trunc], i16::MIN);
60c5eb7d 656 Formatted { sign, parts: digits_to_exp_str(&buf[..len], exp, ndigits, upper, parts) }
d9579d0f
AL
657 }
658 }
659}
660
661/// Formats given floating point number into the decimal form with exactly
662/// given number of fractional digits. The result is stored to the supplied parts
663/// array while utilizing given byte buffer as a scratch. `upper` is currently
664/// unused but left for the future decision to change the case of non-finite values,
0731742a 665/// i.e., `inf` and `nan`. The first part to be rendered is always a `Part::Sign`
d9579d0f
AL
666/// (which can be an empty string if no sign is rendered).
667///
668/// `format_exact` should be the underlying digit-generation function.
669/// You probably would want `strategy::grisu::format_exact` for this.
670///
671/// The byte buffer should be enough for the output unless `frac_digits` is
672/// so large that only the fixed number of digits will be ever written.
673/// (The tipping point for `f64` is about 800, and 1000 bytes should be enough.)
7cac9316
XL
674/// There should be at least 4 parts available, due to the worst case like
675/// `[+][0.][0000][2][0000]` with `frac_digits = 10`.
60c5eb7d
XL
676pub fn to_exact_fixed_str<'a, T, F>(
677 mut format_exact: F,
678 v: T,
679 sign: Sign,
680 frac_digits: usize,
60c5eb7d
XL
681 buf: &'a mut [u8],
682 parts: &'a mut [Part<'a>],
683) -> Formatted<'a>
684where
685 T: DecodableFloat,
686 F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16),
687{
d9579d0f
AL
688 assert!(parts.len() >= 4);
689
690 let (negative, full_decoded) = decode(v);
691 let sign = determine_sign(sign, &full_decoded, negative);
692 match full_decoded {
693 FullDecoded::Nan => {
694 parts[0] = Part::Copy(b"NaN");
b7449926 695 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
696 }
697 FullDecoded::Infinite => {
698 parts[0] = Part::Copy(b"inf");
b7449926 699 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
700 }
701 FullDecoded::Zero => {
60c5eb7d
XL
702 if frac_digits > 0 {
703 // [0.][0000]
d9579d0f
AL
704 parts[0] = Part::Copy(b"0.");
705 parts[1] = Part::Zero(frac_digits);
b7449926 706 Formatted { sign, parts: &parts[..2] }
d9579d0f
AL
707 } else {
708 parts[0] = Part::Copy(b"0");
b7449926 709 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
710 }
711 }
712 FullDecoded::Finite(ref decoded) => {
713 let maxlen = estimate_max_buf_len(decoded.exp);
714 assert!(buf.len() >= maxlen);
715
716 // it *is* possible that `frac_digits` is ridiculously large.
717 // `format_exact` will end rendering digits much earlier in this case,
718 // because we are strictly limited by `maxlen`.
719 let limit = if frac_digits < 0x8000 { -(frac_digits as i16) } else { i16::MIN };
720 let (len, exp) = format_exact(decoded, &mut buf[..maxlen], limit);
721 if exp <= limit {
722 // the restriction couldn't been met, so this should render like zero no matter
723 // `exp` was. this does not include the case that the restriction has been met
724 // only after the final rounding-up; it's a regular case with `exp = limit + 1`.
725 debug_assert_eq!(len, 0);
60c5eb7d
XL
726 if frac_digits > 0 {
727 // [0.][0000]
d9579d0f
AL
728 parts[0] = Part::Copy(b"0.");
729 parts[1] = Part::Zero(frac_digits);
b7449926 730 Formatted { sign, parts: &parts[..2] }
d9579d0f
AL
731 } else {
732 parts[0] = Part::Copy(b"0");
b7449926 733 Formatted { sign, parts: &parts[..1] }
d9579d0f
AL
734 }
735 } else {
60c5eb7d 736 Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
d9579d0f
AL
737 }
738 }
739 }
740}