1 use crate::fmt
::{Debug, Display, Formatter, LowerExp, Result, UpperExp}
;
2 use crate::mem
::MaybeUninit
;
3 use crate::num
::flt2dec
;
5 // Don't inline this so callers don't use the stack space this function
6 // requires unless they have to.
8 fn float_to_decimal_common_exact
<T
>(
9 fmt
: &mut Formatter
<'_
>,
15 T
: flt2dec
::DecodableFloat
,
17 // SAFETY: Possible undefined behavior, see FIXME(#53491)
19 let mut buf
= MaybeUninit
::<[u8; 1024]>::uninit(); // enough for f32 and f64
20 let mut parts
= MaybeUninit
::<[flt2dec
::Part
<'_
>; 4]>::uninit();
21 // FIXME(#53491): This is calling `get_mut` on an uninitialized
22 // `MaybeUninit` (here and elsewhere in this file). Revisit this once
23 // we decided whether that is valid or not.
24 // We can do this only because we are libstd and coupled to the compiler.
25 // (FWIW, using `freeze` would not be enough; `flt2dec::Part` is an enum!)
26 let formatted
= flt2dec
::to_exact_fixed_str(
27 flt2dec
::strategy
::grisu
::format_exact
,
34 fmt
.pad_formatted_parts(&formatted
)
38 // Don't inline this so callers that call both this and the above won't wind
39 // up using the combined stack space of both functions in some cases.
41 fn float_to_decimal_common_shortest
<T
>(
42 fmt
: &mut Formatter
<'_
>,
48 T
: flt2dec
::DecodableFloat
,
50 // SAFETY: Possible undefined behavior, see FIXME(#53491)
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
,
106 // SAFETY: Possible undefined behavior, see FIXME(#53491)
108 let mut buf
= MaybeUninit
::<[u8; 1024]>::uninit(); // enough for f32 and f64
109 let mut parts
= MaybeUninit
::<[flt2dec
::Part
<'_
>; 6]>::uninit();
111 let formatted
= flt2dec
::to_exact_exp_str(
112 flt2dec
::strategy
::grisu
::format_exact
,
120 fmt
.pad_formatted_parts(&formatted
)
124 // Don't inline this so callers that call both this and the above won't wind
125 // up using the combined stack space of both functions in some cases.
127 fn float_to_exponential_common_shortest
<T
>(
128 fmt
: &mut Formatter
<'_
>,
134 T
: flt2dec
::DecodableFloat
,
136 // SAFETY: Possible undefined behavior, see FIXME(#53491)
138 // enough for f32 and f64
139 let mut buf
= MaybeUninit
::<[u8; flt2dec
::MAX_SIG_DIGITS
]>::uninit();
140 let mut parts
= MaybeUninit
::<[flt2dec
::Part
<'_
>; 6]>::uninit();
142 let formatted
= flt2dec
::to_shortest_exp_str(
143 flt2dec
::strategy
::grisu
::format_shortest
,
151 fmt
.pad_formatted_parts(&formatted
)
155 // Common code of floating point LowerExp and UpperExp.
156 fn float_to_exponential_common
<T
>(fmt
: &mut Formatter
<'_
>, num
: &T
, upper
: bool
) -> Result
158 T
: flt2dec
::DecodableFloat
,
160 let force_sign
= fmt
.sign_plus();
161 let sign
= match force_sign
{
162 false => flt2dec
::Sign
::Minus
,
163 true => flt2dec
::Sign
::MinusPlus
,
166 if let Some(precision
) = fmt
.precision
{
167 // 1 integral digit + `precision` fractional digits = `precision + 1` total digits
168 float_to_exponential_common_exact(fmt
, num
, sign
, precision
+ 1, upper
)
170 float_to_exponential_common_shortest(fmt
, num
, sign
, upper
)
174 macro_rules
! floating
{
176 #[stable(feature = "rust1", since = "1.0.0")]
178 fn fmt(&self, fmt
: &mut Formatter
<'_
>) -> Result
{
179 float_to_decimal_common(fmt
, self, true, 1)
183 #[stable(feature = "rust1", since = "1.0.0")]
184 impl Display
for $ty
{
185 fn fmt(&self, fmt
: &mut Formatter
<'_
>) -> Result
{
186 float_to_decimal_common(fmt
, self, false, 0)
190 #[stable(feature = "rust1", since = "1.0.0")]
191 impl LowerExp
for $ty
{
192 fn fmt(&self, fmt
: &mut Formatter
<'_
>) -> Result
{
193 float_to_exponential_common(fmt
, self, false)
197 #[stable(feature = "rust1", since = "1.0.0")]
198 impl UpperExp
for $ty
{
199 fn fmt(&self, fmt
: &mut Formatter
<'_
>) -> Result
{
200 float_to_exponential_common(fmt
, self, true)