3 use crate::f2s_intrinsics
::*;
4 use crate::parse
::Error
;
5 #[cfg(feature = "no-panic")]
6 use no_panic
::no_panic
;
8 const FLOAT_EXPONENT_BIAS
: usize = 127;
10 fn floor_log2(value
: u32) -> u32 {
11 31_u32.wrapping_sub(value
.leading_zeros())
14 #[cfg_attr(feature = "no-panic", no_panic)]
15 pub fn s2f(buffer
: &[u8]) -> Result
<f32, Error
> {
16 let len
= buffer
.len();
18 return Err(Error
::InputTooShort
);
21 let mut m10digits
= 0;
22 let mut e10digits
= 0;
23 let mut dot_index
= len
;
24 let mut e_index
= len
;
27 let mut signed_m
= false;
28 let mut signed_e
= false;
31 if unsafe { *buffer.get_unchecked(0) }
== b'
-'
{
36 while let Some(c
) = buffer
.get(i
).copied() {
39 return Err(Error
::MalformedInput
);
45 if c
< b'
0'
|| c
> b'
9'
{
49 return Err(Error
::InputTooLong
);
51 m10
= 10 * m10
+ (c
- b'
0'
) as u32;
58 if let Some(b'e'
) | Some(b'E'
) = buffer
.get(i
) {
69 while let Some(c
) = buffer
.get(i
).copied() {
70 if c
< b'
0'
|| c
> b'
9'
{
71 return Err(Error
::MalformedInput
);
74 // TODO: Be more lenient. Return +/-Infinity or +/-0 instead.
75 return Err(Error
::InputTooLong
);
77 e10
= 10 * e10
+ (c
- b'
0'
) as i32;
86 return Err(Error
::MalformedInput
);
91 e10
-= if dot_index
< e_index
{
92 (e_index
- dot_index
- 1) as i32
97 return Ok(if signed_m { -0.0 }
else { 0.0 }
);
100 if m10digits
+ e10
<= -46 || m10
== 0 {
101 // Number is less than 1e-46, which should be rounded down to 0; return
103 let ieee
= (signed_m
as u32) << (f2s
::FLOAT_EXPONENT_BITS
+ f2s
::FLOAT_MANTISSA_BITS
);
104 return Ok(f32::from_bits(ieee
));
106 if m10digits
+ e10
>= 40 {
107 // Number is larger than 1e+39, which should be rounded to +/-Infinity.
108 let ieee
= ((signed_m
as u32) << (f2s
::FLOAT_EXPONENT_BITS
+ f2s
::FLOAT_MANTISSA_BITS
))
109 | (0xff_u32 << f2s
::FLOAT_MANTISSA_BITS
);
110 return Ok(f32::from_bits(ieee
));
113 // Convert to binary float m2 * 2^e2, while retaining information about
114 // whether the conversion was exact (trailing_zeros).
117 let mut trailing_zeros
: bool
;
119 // The length of m * 10^e in bits is:
120 // log2(m10 * 10^e10) = log2(m10) + e10 log2(10) = log2(m10) + e10 + e10 * log2(5)
122 // We want to compute the FLOAT_MANTISSA_BITS + 1 top-most bits (+1 for
123 // the implicit leading one in IEEE format). We therefore choose a
124 // binary output exponent of
125 // log2(m10 * 10^e10) - (FLOAT_MANTISSA_BITS + 1).
127 // We use floor(log2(5^e10)) so that we get at least this many bits; better to
128 // have an additional bit than to not have enough bits.
130 .wrapping_add(e10
as u32)
131 .wrapping_add(log2_pow5(e10
) as u32)
132 .wrapping_sub(f2s
::FLOAT_MANTISSA_BITS
+ 1) as i32;
134 // We now compute [m10 * 10^e10 / 2^e2] = [m10 * 5^e10 / 2^(e2-e10)].
135 // To that end, we use the FLOAT_POW5_SPLIT table.
138 .wrapping_sub(ceil_log2_pow5(e10
))
139 .wrapping_add(f2s
::FLOAT_POW5_BITCOUNT
);
140 debug_assert
!(j
>= 0);
141 m2
= mul_pow5_div_pow2(m10
, e10
as u32, j
);
143 // We also compute if the result is exact, i.e.,
144 // [m10 * 10^e10 / 2^e2] == m10 * 10^e10 / 2^e2.
145 // This can only be the case if 2^e2 divides m10 * 10^e10, which in turn
146 // requires that the largest power of 2 that divides m10 + e10 is
147 // greater than e2. If e2 is less than e10, then the result must be
148 // exact. Otherwise we use the existing multiple_of_power_of_2 function.
150 e2
< e10
|| e2
- e10
< 32 && multiple_of_power_of_2_32(m10
, (e2
- e10
) as u32);
153 .wrapping_add(e10
as u32)
154 .wrapping_sub(ceil_log2_pow5(-e10
) as u32)
155 .wrapping_sub(f2s
::FLOAT_MANTISSA_BITS
+ 1) as i32;
157 // We now compute [m10 * 10^e10 / 2^e2] = [m10 / (5^(-e10) 2^(e2-e10))].
160 .wrapping_add(ceil_log2_pow5(-e10
))
162 .wrapping_add(f2s
::FLOAT_POW5_INV_BITCOUNT
);
163 m2
= mul_pow5_inv_div_pow2(m10
, -e10
as u32, j
);
165 // We also compute if the result is exact, i.e.,
166 // [m10 / (5^(-e10) 2^(e2-e10))] == m10 / (5^(-e10) 2^(e2-e10))
168 // If e2-e10 >= 0, we need to check whether (5^(-e10) 2^(e2-e10))
169 // divides m10, which is the case iff pow5(m10) >= -e10 AND pow2(m10) >=
172 // If e2-e10 < 0, we have actually computed [m10 * 2^(e10 e2) /
173 // 5^(-e10)] above, and we need to check whether 5^(-e10) divides (m10 *
174 // 2^(e10-e2)), which is the case iff pow5(m10 * 2^(e10-e2)) = pow5(m10)
176 trailing_zeros
= (e2
< e10
177 || (e2
- e10
< 32 && multiple_of_power_of_2_32(m10
, (e2
- e10
) as u32)))
178 && multiple_of_power_of_5_32(m10
, -e10
as u32);
181 // Compute the final IEEE exponent.
182 let mut ieee_e2
= i32::max(0, e2
+ FLOAT_EXPONENT_BIAS
as i32 + floor_log2(m2
) as i32) as u32;
185 // Final IEEE exponent is larger than the maximum representable; return
187 let ieee
= ((signed_m
as u32) << (f2s
::FLOAT_EXPONENT_BITS
+ f2s
::FLOAT_MANTISSA_BITS
))
188 | (0xff_u32 << f2s
::FLOAT_MANTISSA_BITS
);
189 return Ok(f32::from_bits(ieee
));
192 // We need to figure out how much we need to shift m2. The tricky part is
193 // that we need to take the final IEEE exponent into account, so we need to
194 // reverse the bias and also special-case the value 0.
195 let shift
= if ieee_e2
== 0 { 1 }
else { ieee_e2 as i32 }
197 .wrapping_sub(FLOAT_EXPONENT_BIAS
as i32)
198 .wrapping_sub(f2s
::FLOAT_MANTISSA_BITS
as i32);
199 debug_assert
!(shift
>= 0);
201 // We need to round up if the exact value is more than 0.5 above the value
202 // we computed. That's equivalent to checking if the last removed bit was 1
203 // and either the value was not just trailing zeros or the result would
206 // We need to update trailing_zeros given that we have the exact output
207 // exponent ieee_e2 now.
208 trailing_zeros
&= (m2
& ((1_u32 << (shift
- 1)) - 1)) == 0;
209 let last_removed_bit
= (m2
>> (shift
- 1)) & 1;
210 let round_up
= last_removed_bit
!= 0 && (!trailing_zeros
|| ((m2
>> shift
) & 1) != 0);
212 let mut ieee_m2
= (m2
>> shift
).wrapping_add(round_up
as u32);
213 debug_assert
!(ieee_m2
<= 1_u32 << (f2s
::FLOAT_MANTISSA_BITS
+ 1));
214 ieee_m2
&= (1_u32 << f2s
::FLOAT_MANTISSA_BITS
) - 1;
215 if ieee_m2
== 0 && round_up
{
216 // Rounding up may overflow the mantissa.
217 // In this case we move a trailing zero of the mantissa into the
219 // Due to how the IEEE represents +/-Infinity, we don't need to check
220 // for overflow here.
223 let ieee
= ((((signed_m
as u32) << f2s
::FLOAT_EXPONENT_BITS
) | ieee_e2
as u32)
224 << f2s
::FLOAT_MANTISSA_BITS
)
226 Ok(f32::from_bits(ieee
))