]> git.lizzy.rs Git - rust.git/blob - src/libcore/fmt/float.rs
Rollup merge of #39604 - est31:i128_tests, r=alexcrichton
[rust.git] / src / libcore / fmt / float.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug};
12 use num::flt2dec;
13
14 // Common code of floating point Debug and Display.
15 fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool) -> Result
16     where T: flt2dec::DecodableFloat
17 {
18     let force_sign = fmt.sign_plus();
19     let sign = match (force_sign, negative_zero) {
20         (false, false) => flt2dec::Sign::Minus,
21         (false, true)  => flt2dec::Sign::MinusRaw,
22         (true,  false) => flt2dec::Sign::MinusPlus,
23         (true,  true)  => flt2dec::Sign::MinusPlusRaw,
24     };
25
26     let mut buf = [0; 1024]; // enough for f32 and f64
27     let mut parts = [flt2dec::Part::Zero(0); 16];
28     let formatted = if let Some(precision) = fmt.precision {
29         flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, *num, sign,
30                                     precision, false, &mut buf, &mut parts)
31     } else {
32         flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign,
33                                  0, false, &mut buf, &mut parts)
34     };
35     fmt.pad_formatted_parts(&formatted)
36 }
37
38 // Common code of floating point LowerExp and UpperExp.
39 fn float_to_exponential_common<T>(fmt: &mut Formatter, num: &T, upper: bool) -> Result
40     where T: flt2dec::DecodableFloat
41 {
42     let force_sign = fmt.sign_plus();
43     let sign = match force_sign {
44         false => flt2dec::Sign::Minus,
45         true  => flt2dec::Sign::MinusPlus,
46     };
47
48     let mut buf = [0; 1024]; // enough for f32 and f64
49     let mut parts = [flt2dec::Part::Zero(0); 16];
50     let formatted = if let Some(precision) = fmt.precision {
51         // 1 integral digit + `precision` fractional digits = `precision + 1` total digits
52         flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign,
53                                   precision + 1, upper, &mut buf, &mut parts)
54     } else {
55         flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign,
56                                      (0, 0), upper, &mut buf, &mut parts)
57     };
58     fmt.pad_formatted_parts(&formatted)
59 }
60
61 macro_rules! floating {
62     ($ty:ident) => (
63         #[stable(feature = "rust1", since = "1.0.0")]
64         impl Debug for $ty {
65             fn fmt(&self, fmt: &mut Formatter) -> Result {
66                 float_to_decimal_common(fmt, self, true)
67             }
68         }
69
70         #[stable(feature = "rust1", since = "1.0.0")]
71         impl Display for $ty {
72             fn fmt(&self, fmt: &mut Formatter) -> Result {
73                 float_to_decimal_common(fmt, self, false)
74             }
75         }
76
77         #[stable(feature = "rust1", since = "1.0.0")]
78         impl LowerExp for $ty {
79             fn fmt(&self, fmt: &mut Formatter) -> Result {
80                 float_to_exponential_common(fmt, self, false)
81             }
82         }
83
84         #[stable(feature = "rust1", since = "1.0.0")]
85         impl UpperExp for $ty {
86             fn fmt(&self, fmt: &mut Formatter) -> Result {
87                 float_to_exponential_common(fmt, self, true)
88             }
89         }
90     )
91 }
92
93 floating! { f32 }
94 floating! { f64 }