diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 50248fabfcd..60c291ef845 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -11,6 +11,35 @@ use fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug}; use num::flt2dec; +// 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 = [0; 1024]; // enough for f32 and f64 + let mut parts = [flt2dec::Part::Zero(0); 16]; + let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, + *num, sign, precision, + false, &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) -> Result + where T: flt2dec::DecodableFloat +{ + let mut buf = [0; flt2dec::MAX_SIG_DIGITS]; // enough for f32 and f64 + let mut parts = [flt2dec::Part::Zero(0); 16]; + let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, + *num, sign, 0, false, &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, negative_zero: bool) -> Result where T: flt2dec::DecodableFloat @@ -23,15 +52,41 @@ fn float_to_decimal_common(fmt: &mut Formatter, num: &T, negative_zero: bool) (true, true) => flt2dec::Sign::MinusPlusRaw, }; + if let Some(precision) = fmt.precision { + float_to_decimal_common_exact(fmt, num, sign, precision) + } else { + float_to_decimal_common_shortest(fmt, num, sign) + } +} + +// 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 = [0; 1024]; // enough for f32 and f64 let mut parts = [flt2dec::Part::Zero(0); 16]; - let formatted = if let Some(precision) = fmt.precision { - flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, *num, sign, - precision, false, &mut buf, &mut parts) - } else { - flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign, - 0, false, &mut buf, &mut parts) - }; + 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 +{ + let mut buf = [0; flt2dec::MAX_SIG_DIGITS]; // enough for f32 and f64 + let mut parts = [flt2dec::Part::Zero(0); 16]; + 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) } @@ -45,17 +100,12 @@ fn float_to_exponential_common(fmt: &mut Formatter, num: &T, upper: bool) -> true => flt2dec::Sign::MinusPlus, }; - let mut buf = [0; 1024]; // enough for f32 and f64 - let mut parts = [flt2dec::Part::Zero(0); 16]; - let formatted = if let Some(precision) = fmt.precision { + if let Some(precision) = fmt.precision { // 1 integral digit + `precision` fractional digits = `precision + 1` total digits - flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign, - precision + 1, upper, &mut buf, &mut parts) + float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper) } else { - flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign, - (0, 0), upper, &mut buf, &mut parts) - }; - fmt.pad_formatted_parts(&formatted) + float_to_exponential_common_shortest(fmt, num, sign, upper) + } } macro_rules! floating {