1 use crate::fmt::{Debug, Display, Formatter, LowerExp, Result, UpperExp};
2 use crate::mem::MaybeUninit;
3 use crate::num::flt2dec;
5 // ignore-tidy-undocumented-unsafe
7 // Don't inline this so callers don't use the stack space this function
8 // requires unless they have to.
10 fn float_to_decimal_common_exact<T>(
11 fmt: &mut Formatter<'_>,
17 T: flt2dec::DecodableFloat,
20 let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
21 let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit();
22 // FIXME(#53491): This is calling `get_mut` on an uninitialized
23 // `MaybeUninit` (here and elsewhere in this file). Revisit this once
24 // we decided whether that is valid or not.
25 // We can do this only because we are libstd and coupled to the compiler.
26 // (FWIW, using `freeze` would not be enough; `flt2dec::Part` is an enum!)
27 let formatted = flt2dec::to_exact_fixed_str(
28 flt2dec::strategy::grisu::format_exact,
35 fmt.pad_formatted_parts(&formatted)
39 // Don't inline this so callers that call both this and the above won't wind
40 // up using the combined stack space of both functions in some cases.
42 fn float_to_decimal_common_shortest<T>(
43 fmt: &mut Formatter<'_>,
49 T: flt2dec::DecodableFloat,
52 // enough for f32 and f64
53 let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit();
54 let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit();
56 let formatted = flt2dec::to_shortest_str(
57 flt2dec::strategy::grisu::format_shortest,
64 fmt.pad_formatted_parts(&formatted)
68 // Common code of floating point Debug and Display.
69 fn float_to_decimal_common<T>(
70 fmt: &mut Formatter<'_>,
76 T: flt2dec::DecodableFloat,
78 let force_sign = fmt.sign_plus();
79 let sign = match (force_sign, negative_zero) {
80 (false, false) => flt2dec::Sign::Minus,
81 (false, true) => flt2dec::Sign::MinusRaw,
82 (true, false) => flt2dec::Sign::MinusPlus,
83 (true, true) => flt2dec::Sign::MinusPlusRaw,
86 if let Some(precision) = fmt.precision {
87 float_to_decimal_common_exact(fmt, num, sign, precision)
89 float_to_decimal_common_shortest(fmt, num, sign, min_precision)
93 // Don't inline this so callers don't use the stack space this function
94 // requires unless they have to.
96 fn float_to_exponential_common_exact<T>(
97 fmt: &mut Formatter<'_>,
104 T: flt2dec::DecodableFloat,
107 let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
108 let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit();
110 let formatted = flt2dec::to_exact_exp_str(
111 flt2dec::strategy::grisu::format_exact,
119 fmt.pad_formatted_parts(&formatted)
123 // Don't inline this so callers that call both this and the above won't wind
124 // up using the combined stack space of both functions in some cases.
126 fn float_to_exponential_common_shortest<T>(
127 fmt: &mut Formatter<'_>,
133 T: flt2dec::DecodableFloat,
136 // enough for f32 and f64
137 let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit();
138 let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit();
140 let formatted = flt2dec::to_shortest_exp_str(
141 flt2dec::strategy::grisu::format_shortest,
149 fmt.pad_formatted_parts(&formatted)
153 // Common code of floating point LowerExp and UpperExp.
154 fn float_to_exponential_common<T>(fmt: &mut Formatter<'_>, num: &T, upper: bool) -> Result
156 T: flt2dec::DecodableFloat,
158 let force_sign = fmt.sign_plus();
159 let sign = match force_sign {
160 false => flt2dec::Sign::Minus,
161 true => flt2dec::Sign::MinusPlus,
164 if let Some(precision) = fmt.precision {
165 // 1 integral digit + `precision` fractional digits = `precision + 1` total digits
166 float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper)
168 float_to_exponential_common_shortest(fmt, num, sign, upper)
172 macro_rules! floating {
174 #[stable(feature = "rust1", since = "1.0.0")]
176 fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
177 float_to_decimal_common(fmt, self, true, 1)
181 #[stable(feature = "rust1", since = "1.0.0")]
182 impl Display for $ty {
183 fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
184 float_to_decimal_common(fmt, self, false, 0)
188 #[stable(feature = "rust1", since = "1.0.0")]
189 impl LowerExp for $ty {
190 fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
191 float_to_exponential_common(fmt, self, false)
195 #[stable(feature = "rust1", since = "1.0.0")]
196 impl UpperExp for $ty {
197 fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
198 float_to_exponential_common(fmt, self, true)