99// except according to those terms.
1010
1111use fmt:: { Formatter , Result , LowerExp , UpperExp , Display , Debug } ;
12+ use mem;
1213use num:: flt2dec;
1314
15+ // Don't inline this so callers don't use the stack space this function
16+ // requires unless they have to.
17+ #[ inline( never) ]
18+ fn float_to_decimal_common_exact < T > ( fmt : & mut Formatter , num : & T ,
19+ sign : flt2dec:: Sign , precision : usize ) -> Result
20+ where T : flt2dec:: DecodableFloat
21+ {
22+ unsafe {
23+ let mut buf: [ u8 ; 1024 ] = mem:: uninitialized ( ) ; // enough for f32 and f64
24+ let mut parts: [ flt2dec:: Part ; 5 ] = mem:: uninitialized ( ) ;
25+ let formatted = flt2dec:: to_exact_fixed_str ( flt2dec:: strategy:: grisu:: format_exact,
26+ * num, sign, precision,
27+ false , & mut buf, & mut parts) ;
28+ fmt. pad_formatted_parts ( & formatted)
29+ }
30+ }
31+
32+ // Don't inline this so callers that call both this and the above won't wind
33+ // up using the combined stack space of both functions in some cases.
34+ #[ inline( never) ]
35+ fn float_to_decimal_common_shortest < T > ( fmt : & mut Formatter ,
36+ num : & T , sign : flt2dec:: Sign ) -> Result
37+ where T : flt2dec:: DecodableFloat
38+ {
39+ unsafe {
40+ // enough for f32 and f64
41+ let mut buf: [ u8 ; flt2dec:: MAX_SIG_DIGITS ] = mem:: uninitialized ( ) ;
42+ let mut parts: [ flt2dec:: Part ; 5 ] = mem:: uninitialized ( ) ;
43+ let formatted = flt2dec:: to_shortest_str ( flt2dec:: strategy:: grisu:: format_shortest,
44+ * num, sign, 0 , false , & mut buf, & mut parts) ;
45+ fmt. pad_formatted_parts ( & formatted)
46+ }
47+ }
48+
1449// Common code of floating point Debug and Display.
1550fn float_to_decimal_common < T > ( fmt : & mut Formatter , num : & T , negative_zero : bool ) -> Result
1651 where T : flt2dec:: DecodableFloat
@@ -23,16 +58,48 @@ fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool)
2358 ( true , true ) => flt2dec:: Sign :: MinusPlusRaw ,
2459 } ;
2560
26- let mut buf = [ 0 ; 1024 ] ; // enough for f32 and f64
27- let mut parts = [ flt2dec:: Part :: Zero ( 0 ) ; 16 ] ;
28- let formatted = if let Some ( precision) = fmt. precision {
29- flt2dec:: to_exact_fixed_str ( flt2dec:: strategy:: grisu:: format_exact, * num, sign,
30- precision, false , & mut buf, & mut parts)
61+ if let Some ( precision) = fmt. precision {
62+ float_to_decimal_common_exact ( fmt, num, sign, precision)
3163 } else {
32- flt2dec:: to_shortest_str ( flt2dec:: strategy:: grisu:: format_shortest, * num, sign,
33- 0 , false , & mut buf, & mut parts)
34- } ;
35- fmt. pad_formatted_parts ( & formatted)
64+ float_to_decimal_common_shortest ( fmt, num, sign)
65+ }
66+ }
67+
68+ // Don't inline this so callers don't use the stack space this function
69+ // requires unless they have to.
70+ #[ inline( never) ]
71+ fn float_to_exponential_common_exact < T > ( fmt : & mut Formatter , num : & T ,
72+ sign : flt2dec:: Sign , precision : usize ,
73+ upper : bool ) -> Result
74+ where T : flt2dec:: DecodableFloat
75+ {
76+ unsafe {
77+ let mut buf: [ u8 ; 1024 ] = mem:: uninitialized ( ) ; // enough for f32 and f64
78+ let mut parts: [ flt2dec:: Part ; 7 ] = mem:: uninitialized ( ) ;
79+ let formatted = flt2dec:: to_exact_exp_str ( flt2dec:: strategy:: grisu:: format_exact,
80+ * num, sign, precision,
81+ upper, & mut buf, & mut parts) ;
82+ fmt. pad_formatted_parts ( & formatted)
83+ }
84+ }
85+
86+ // Don't inline this so callers that call both this and the above won't wind
87+ // up using the combined stack space of both functions in some cases.
88+ #[ inline( never) ]
89+ fn float_to_exponential_common_shortest < T > ( fmt : & mut Formatter ,
90+ num : & T , sign : flt2dec:: Sign ,
91+ upper : bool ) -> Result
92+ where T : flt2dec:: DecodableFloat
93+ {
94+ unsafe {
95+ // enough for f32 and f64
96+ let mut buf: [ u8 ; flt2dec:: MAX_SIG_DIGITS ] = mem:: uninitialized ( ) ;
97+ let mut parts: [ flt2dec:: Part ; 7 ] = mem:: uninitialized ( ) ;
98+ let formatted = flt2dec:: to_shortest_exp_str ( flt2dec:: strategy:: grisu:: format_shortest,
99+ * num, sign, ( 0 , 0 ) , upper,
100+ & mut buf, & mut parts) ;
101+ fmt. pad_formatted_parts ( & formatted)
102+ }
36103}
37104
38105// Common code of floating point LowerExp and UpperExp.
@@ -45,17 +112,12 @@ fn float_to_exponential_common<T>(fmt: &mut Formatter, num: &T, upper: bool) ->
45112 true => flt2dec:: Sign :: MinusPlus ,
46113 } ;
47114
48- let mut buf = [ 0 ; 1024 ] ; // enough for f32 and f64
49- let mut parts = [ flt2dec:: Part :: Zero ( 0 ) ; 16 ] ;
50- let formatted = if let Some ( precision) = fmt. precision {
115+ if let Some ( precision) = fmt. precision {
51116 // 1 integral digit + `precision` fractional digits = `precision + 1` total digits
52- flt2dec:: to_exact_exp_str ( flt2dec:: strategy:: grisu:: format_exact, * num, sign,
53- precision + 1 , upper, & mut buf, & mut parts)
117+ float_to_exponential_common_exact ( fmt, num, sign, precision + 1 , upper)
54118 } else {
55- flt2dec:: to_shortest_exp_str ( flt2dec:: strategy:: grisu:: format_shortest, * num, sign,
56- ( 0 , 0 ) , upper, & mut buf, & mut parts)
57- } ;
58- fmt. pad_formatted_parts ( & formatted)
119+ float_to_exponential_common_shortest ( fmt, num, sign, upper)
120+ }
59121}
60122
61123macro_rules! floating {
0 commit comments