1use crate::common::*;
2use crate::f2s;
3use crate::f2s_intrinsics::*;
4use crate::parse::Error;
5#[cfg(feature = "no-panic")]
6use no_panic::no_panic;
7
8const FLOAT_EXPONENT_BIAS: usize = 127;
9
10fn floor_log2(value: u32) -> u32 {
11 31_u32.wrapping_sub(value.leading_zeros())
12}
13
14#[cfg_attr(feature = "no-panic", no_panic)]
15pub fn s2f(buffer: &[u8]) -> Result<f32, Error> {
16 let len = buffer.len();
17 if len == 0 {
18 return Err(Error::InputTooShort);
19 }
20
21 let mut m10digits = 0;
22 let mut e10digits = 0;
23 let mut dot_index = len;
24 let mut e_index = len;
25 let mut m10 = 0u32;
26 let mut e10 = 0i32;
27 let mut signed_m = false;
28 let mut signed_e = false;
29
30 let mut i = 0;
31 if unsafe { *buffer.get_unchecked(0) } == b'-' {
32 signed_m = true;
33 i += 1;
34 }
35
36 while let Some(c) = buffer.get(i).copied() {
37 if c == b'.' {
38 if dot_index != len {
39 return Err(Error::MalformedInput);
40 }
41 dot_index = i;
42 i += 1;
43 continue;
44 }
45 if c < b'0' || c > b'9' {
46 break;
47 }
48 if m10digits >= 9 {
49 return Err(Error::InputTooLong);
50 }
51 m10 = 10 * m10 + (c - b'0') as u32;
52 if m10 != 0 {
53 m10digits += 1;
54 }
55 i += 1;
56 }
57
58 if let Some(b'e') | Some(b'E') = buffer.get(i) {
59 e_index = i;
60 i += 1;
61 match buffer.get(i) {
62 Some(b'-') => {
63 signed_e = true;
64 i += 1;
65 }
66 Some(b'+') => i += 1,
67 _ => {}
68 }
69 while let Some(c) = buffer.get(i).copied() {
70 if c < b'0' || c > b'9' {
71 return Err(Error::MalformedInput);
72 }
73 if e10digits > 3 {
74 // TODO: Be more lenient. Return +/-Infinity or +/-0 instead.
75 return Err(Error::InputTooLong);
76 }
77 e10 = 10 * e10 + (c - b'0') as i32;
78 if e10 != 0 {
79 e10digits += 1;
80 }
81 i += 1;
82 }
83 }
84
85 if i < len {
86 return Err(Error::MalformedInput);
87 }
88 if signed_e {
89 e10 = -e10;
90 }
91 e10 -= if dot_index < e_index {
92 (e_index - dot_index - 1) as i32
93 } else {
94 0
95 };
96 if m10 == 0 {
97 return Ok(if signed_m { -0.0 } else { 0.0 });
98 }
99
100 if m10digits + e10 <= -46 || m10 == 0 {
101 // Number is less than 1e-46, which should be rounded down to 0; return
102 // +/-0.0.
103 let ieee = (signed_m as u32) << (f2s::FLOAT_EXPONENT_BITS + f2s::FLOAT_MANTISSA_BITS);
104 return Ok(f32::from_bits(ieee));
105 }
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));
111 }
112
113 // Convert to binary float m2 * 2^e2, while retaining information about
114 // whether the conversion was exact (trailing_zeros).
115 let e2: i32;
116 let m2: u32;
117 let mut trailing_zeros: bool;
118 if e10 >= 0 {
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)
121 //
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).
126 //
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.
129 e2 = floor_log2(m10)
130 .wrapping_add(e10 as u32)
131 .wrapping_add(log2_pow5(e10) as u32)
132 .wrapping_sub(f2s::FLOAT_MANTISSA_BITS + 1) as i32;
133
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.
136 let j = e2
137 .wrapping_sub(e10)
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);
142
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.
149 trailing_zeros =
150 e2 < e10 || e2 - e10 < 32 && multiple_of_power_of_2_32(m10, (e2 - e10) as u32);
151 } else {
152 e2 = floor_log2(m10)
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;
156
157 // We now compute [m10 * 10^e10 / 2^e2] = [m10 / (5^(-e10) 2^(e2-e10))].
158 let j = e2
159 .wrapping_sub(e10)
160 .wrapping_add(ceil_log2_pow5(-e10))
161 .wrapping_sub(1)
162 .wrapping_add(f2s::FLOAT_POW5_INV_BITCOUNT);
163 m2 = mul_pow5_inv_div_pow2(m10, -e10 as u32, j);
164
165 // We also compute if the result is exact, i.e.,
166 // [m10 / (5^(-e10) 2^(e2-e10))] == m10 / (5^(-e10) 2^(e2-e10))
167 //
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) >=
170 // e2-e10.
171 //
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)
175 // >= -e10.
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);
179 }
180
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;
183
184 if ieee_e2 > 0xfe {
185 // Final IEEE exponent is larger than the maximum representable; return
186 // +/-Infinity.
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));
190 }
191
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 }
196 .wrapping_sub(e2)
197 .wrapping_sub(FLOAT_EXPONENT_BIAS as i32)
198 .wrapping_sub(f2s::FLOAT_MANTISSA_BITS as i32);
199 debug_assert!(shift >= 0);
200
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
204 // otherwise be odd.
205 //
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);
211
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
218 // exponent.
219 // Due to how the IEEE represents +/-Infinity, we don't need to check
220 // for overflow here.
221 ieee_e2 += 1;
222 }
223 let ieee = ((((signed_m as u32) << f2s::FLOAT_EXPONENT_BITS) | ieee_e2)
224 << f2s::FLOAT_MANTISSA_BITS)
225 | ieee_m2;
226 Ok(f32::from_bits(ieee))
227}
228