1 use fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug};
5 // Don't inline this so callers don't use the stack space this function
6 // requires unless they have to.
8 fn float_to_decimal_common_exact<T>(fmt: &mut Formatter, num: &T,
9 sign: flt2dec::Sign, precision: usize) -> Result
10 where T: flt2dec::DecodableFloat
13 let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64
14 let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized();
15 // FIXME(#53491): Technically, this is calling `get_mut` on an uninitialized
16 // `MaybeUninit` (here and elsewhere in this file). Revisit this once
17 // we decided whether that is valid or not.
18 // Using `freeze` is *not enough*; `flt2dec::Part` is an enum!
19 let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
20 *num, sign, precision,
21 false, buf.get_mut(), parts.get_mut());
22 fmt.pad_formatted_parts(&formatted)
26 // Don't inline this so callers that call both this and the above won't wind
27 // up using the combined stack space of both functions in some cases.
29 fn float_to_decimal_common_shortest<T>(fmt: &mut Formatter, num: &T,
30 sign: flt2dec::Sign, precision: usize) -> Result
31 where T: flt2dec::DecodableFloat
34 // enough for f32 and f64
35 let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized();
36 let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized();
38 let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num,
39 sign, precision, false, buf.get_mut(),
41 fmt.pad_formatted_parts(&formatted)
45 // Common code of floating point Debug and Display.
46 fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T,
47 negative_zero: bool, min_precision: usize) -> Result
48 where T: flt2dec::DecodableFloat
50 let force_sign = fmt.sign_plus();
51 let sign = match (force_sign, negative_zero) {
52 (false, false) => flt2dec::Sign::Minus,
53 (false, true) => flt2dec::Sign::MinusRaw,
54 (true, false) => flt2dec::Sign::MinusPlus,
55 (true, true) => flt2dec::Sign::MinusPlusRaw,
58 if let Some(precision) = fmt.precision {
59 float_to_decimal_common_exact(fmt, num, sign, precision)
61 float_to_decimal_common_shortest(fmt, num, sign, min_precision)
65 // Don't inline this so callers don't use the stack space this function
66 // requires unless they have to.
68 fn float_to_exponential_common_exact<T>(fmt: &mut Formatter, num: &T,
69 sign: flt2dec::Sign, precision: usize,
70 upper: bool) -> Result
71 where T: flt2dec::DecodableFloat
74 let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64
75 let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized();
77 let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact,
78 *num, sign, precision,
79 upper, buf.get_mut(), parts.get_mut());
80 fmt.pad_formatted_parts(&formatted)
84 // Don't inline this so callers that call both this and the above won't wind
85 // up using the combined stack space of both functions in some cases.
87 fn float_to_exponential_common_shortest<T>(fmt: &mut Formatter,
88 num: &T, sign: flt2dec::Sign,
89 upper: bool) -> Result
90 where T: flt2dec::DecodableFloat
93 // enough for f32 and f64
94 let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized();
95 let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized();
97 let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest,
98 *num, sign, (0, 0), upper,
99 buf.get_mut(), parts.get_mut());
100 fmt.pad_formatted_parts(&formatted)
104 // Common code of floating point LowerExp and UpperExp.
105 fn float_to_exponential_common<T>(fmt: &mut Formatter, num: &T, upper: bool) -> Result
106 where T: flt2dec::DecodableFloat
108 let force_sign = fmt.sign_plus();
109 let sign = match force_sign {
110 false => flt2dec::Sign::Minus,
111 true => flt2dec::Sign::MinusPlus,
114 if let Some(precision) = fmt.precision {
115 // 1 integral digit + `precision` fractional digits = `precision + 1` total digits
116 float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper)
118 float_to_exponential_common_shortest(fmt, num, sign, upper)
122 macro_rules! floating {
124 #[stable(feature = "rust1", since = "1.0.0")]
126 fn fmt(&self, fmt: &mut Formatter) -> Result {
127 float_to_decimal_common(fmt, self, true, 1)
131 #[stable(feature = "rust1", since = "1.0.0")]
132 impl Display for $ty {
133 fn fmt(&self, fmt: &mut Formatter) -> Result {
134 float_to_decimal_common(fmt, self, false, 0)
138 #[stable(feature = "rust1", since = "1.0.0")]
139 impl LowerExp for $ty {
140 fn fmt(&self, fmt: &mut Formatter) -> Result {
141 float_to_exponential_common(fmt, self, false)
145 #[stable(feature = "rust1", since = "1.0.0")]
146 impl UpperExp for $ty {
147 fn fmt(&self, fmt: &mut Formatter) -> Result {
148 float_to_exponential_common(fmt, self, true)