about summary refs log tree commit diff
path: root/src/libcore/fmt/float.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore/fmt/float.rs')
-rw-r--r--src/libcore/fmt/float.rs82
1 files changed, 66 insertions, 16 deletions
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<T>(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<T>(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<T>(fmt: &mut Formatter, num: &T, negative_zero: bool) -> Result
     where T: flt2dec::DecodableFloat
@@ -23,15 +52,41 @@ fn float_to_decimal_common<T>(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<T>(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<T>(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<T>(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 {