use crate::fmt::{Debug, Display, Formatter, LowerExp, Result, UpperExp}; use crate::mem::MaybeUninit; use crate::num::flt2dec; use crate::num::fmt as numfmt; // Don't inline this so callers don't use the stack space this function // requires unless they have to. #[inline(never)] fn float_to_decimal_common_exact( fmt: &mut Formatter<'_>, num: &T, sign: flt2dec::Sign, precision: usize, ) -> Result where T: flt2dec::DecodableFloat, { let mut buf: [MaybeUninit; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64 let mut parts: [MaybeUninit>; 4] = MaybeUninit::uninit_array(); let formatted = flt2dec::to_exact_fixed_str( flt2dec::strategy::grisu::format_exact, *num, sign, precision, &mut buf, &mut parts, ); fmt.pad_formatted_parts(&formatted) } // Don't inline this so callers that call both this and the above won't wind // up using the combined stack space of both functions in some cases. #[inline(never)] fn float_to_decimal_common_shortest( fmt: &mut Formatter<'_>, num: &T, sign: flt2dec::Sign, precision: usize, ) -> Result where T: flt2dec::DecodableFloat, { // enough for f32 and f64 let mut buf: [MaybeUninit; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array(); let mut parts: [MaybeUninit>; 4] = MaybeUninit::uninit_array(); let formatted = flt2dec::to_shortest_str( flt2dec::strategy::grisu::format_shortest, *num, sign, precision, &mut buf, &mut parts, ); fmt.pad_formatted_parts(&formatted) } // Common code of floating point Debug and Display. fn float_to_decimal_common(fmt: &mut Formatter<'_>, num: &T, min_precision: usize) -> Result where T: flt2dec::DecodableFloat, { let force_sign = fmt.sign_plus(); let sign = match force_sign { false => flt2dec::Sign::Minus, true => flt2dec::Sign::MinusPlus, }; if let Some(precision) = fmt.precision { float_to_decimal_common_exact(fmt, num, sign, precision) } else { float_to_decimal_common_shortest(fmt, num, sign, min_precision) } } // Don't inline this so callers don't use the stack space this function // requires unless they have to. #[inline(never)] fn float_to_exponential_common_exact( fmt: &mut Formatter<'_>, num: &T, sign: flt2dec::Sign, precision: usize, upper: bool, ) -> Result where T: flt2dec::DecodableFloat, { let mut buf: [MaybeUninit; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64 let mut parts: [MaybeUninit>; 6] = MaybeUninit::uninit_array(); let formatted = flt2dec::to_exact_exp_str( flt2dec::strategy::grisu::format_exact, *num, sign, precision, upper, &mut buf, &mut parts, ); fmt.pad_formatted_parts(&formatted) } // Don't inline this so callers that call both this and the above won't wind // up using the combined stack space of both functions in some cases. #[inline(never)] fn float_to_exponential_common_shortest( fmt: &mut Formatter<'_>, num: &T, sign: flt2dec::Sign, upper: bool, ) -> Result where T: flt2dec::DecodableFloat, { // enough for f32 and f64 let mut buf: [MaybeUninit; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array(); let mut parts: [MaybeUninit>; 6] = MaybeUninit::uninit_array(); let formatted = flt2dec::to_shortest_exp_str( flt2dec::strategy::grisu::format_shortest, *num, sign, (0, 0), upper, &mut buf, &mut parts, ); fmt.pad_formatted_parts(&formatted) } // Common code of floating point LowerExp and UpperExp. fn float_to_exponential_common(fmt: &mut Formatter<'_>, num: &T, upper: bool) -> Result where T: flt2dec::DecodableFloat, { let force_sign = fmt.sign_plus(); let sign = match force_sign { false => flt2dec::Sign::Minus, true => flt2dec::Sign::MinusPlus, }; if let Some(precision) = fmt.precision { // 1 integral digit + `precision` fractional digits = `precision + 1` total digits float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper) } else { float_to_exponential_common_shortest(fmt, num, sign, upper) } } macro_rules! floating { ($ty:ident) => { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for $ty { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { float_to_decimal_common(fmt, self, 1) } } #[stable(feature = "rust1", since = "1.0.0")] impl Display for $ty { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { float_to_decimal_common(fmt, self, 0) } } #[stable(feature = "rust1", since = "1.0.0")] impl LowerExp for $ty { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { float_to_exponential_common(fmt, self, false) } } #[stable(feature = "rust1", since = "1.0.0")] impl UpperExp for $ty { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { float_to_exponential_common(fmt, self, true) } } }; } floating! { f32 } floating! { f64 }