xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/ryu-1.0.17/src/s2f.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 use crate::common::{ceil_log2_pow5, log2_pow5};
2 use crate::f2s;
3 use crate::f2s_intrinsics::{
4     mul_pow5_div_pow2, mul_pow5_inv_div_pow2, multiple_of_power_of_2_32, multiple_of_power_of_5_32,
5 };
6 use crate::parse::Error;
7 #[cfg(feature = "no-panic")]
8 use no_panic::no_panic;
9 
10 const FLOAT_EXPONENT_BIAS: usize = 127;
11 
floor_log2(value: u32) -> u3212 fn floor_log2(value: u32) -> u32 {
13     31_u32.wrapping_sub(value.leading_zeros())
14 }
15 
16 #[cfg_attr(feature = "no-panic", no_panic)]
s2f(buffer: &[u8]) -> Result<f32, Error>17 pub fn s2f(buffer: &[u8]) -> Result<f32, Error> {
18     let len = buffer.len();
19     if len == 0 {
20         return Err(Error::InputTooShort);
21     }
22 
23     let mut m10digits = 0;
24     let mut e10digits = 0;
25     let mut dot_index = len;
26     let mut e_index = len;
27     let mut m10 = 0u32;
28     let mut e10 = 0i32;
29     let mut signed_m = false;
30     let mut signed_e = false;
31 
32     let mut i = 0;
33     if unsafe { *buffer.get_unchecked(0) } == b'-' {
34         signed_m = true;
35         i += 1;
36     }
37 
38     while let Some(c) = buffer.get(i).copied() {
39         if c == b'.' {
40             if dot_index != len {
41                 return Err(Error::MalformedInput);
42             }
43             dot_index = i;
44             i += 1;
45             continue;
46         }
47         if c < b'0' || c > b'9' {
48             break;
49         }
50         if m10digits >= 9 {
51             return Err(Error::InputTooLong);
52         }
53         m10 = 10 * m10 + (c - b'0') as u32;
54         if m10 != 0 {
55             m10digits += 1;
56         }
57         i += 1;
58     }
59 
60     if let Some(b'e') | Some(b'E') = buffer.get(i) {
61         e_index = i;
62         i += 1;
63         match buffer.get(i) {
64             Some(b'-') => {
65                 signed_e = true;
66                 i += 1;
67             }
68             Some(b'+') => i += 1,
69             _ => {}
70         }
71         while let Some(c) = buffer.get(i).copied() {
72             if c < b'0' || c > b'9' {
73                 return Err(Error::MalformedInput);
74             }
75             if e10digits > 3 {
76                 // TODO: Be more lenient. Return +/-Infinity or +/-0 instead.
77                 return Err(Error::InputTooLong);
78             }
79             e10 = 10 * e10 + (c - b'0') as i32;
80             if e10 != 0 {
81                 e10digits += 1;
82             }
83             i += 1;
84         }
85     }
86 
87     if i < len {
88         return Err(Error::MalformedInput);
89     }
90     if signed_e {
91         e10 = -e10;
92     }
93     e10 -= if dot_index < e_index {
94         (e_index - dot_index - 1) as i32
95     } else {
96         0
97     };
98     if m10 == 0 {
99         return Ok(if signed_m { -0.0 } else { 0.0 });
100     }
101 
102     if m10digits + e10 <= -46 || m10 == 0 {
103         // Number is less than 1e-46, which should be rounded down to 0; return
104         // +/-0.0.
105         let ieee = (signed_m as u32) << (f2s::FLOAT_EXPONENT_BITS + f2s::FLOAT_MANTISSA_BITS);
106         return Ok(f32::from_bits(ieee));
107     }
108     if m10digits + e10 >= 40 {
109         // Number is larger than 1e+39, which should be rounded to +/-Infinity.
110         let ieee = ((signed_m as u32) << (f2s::FLOAT_EXPONENT_BITS + f2s::FLOAT_MANTISSA_BITS))
111             | (0xff_u32 << f2s::FLOAT_MANTISSA_BITS);
112         return Ok(f32::from_bits(ieee));
113     }
114 
115     // Convert to binary float m2 * 2^e2, while retaining information about
116     // whether the conversion was exact (trailing_zeros).
117     let e2: i32;
118     let m2: u32;
119     let mut trailing_zeros: bool;
120     if e10 >= 0 {
121         // The length of m * 10^e in bits is:
122         //   log2(m10 * 10^e10) = log2(m10) + e10 log2(10) = log2(m10) + e10 + e10 * log2(5)
123         //
124         // We want to compute the FLOAT_MANTISSA_BITS + 1 top-most bits (+1 for
125         // the implicit leading one in IEEE format). We therefore choose a
126         // binary output exponent of
127         //   log2(m10 * 10^e10) - (FLOAT_MANTISSA_BITS + 1).
128         //
129         // We use floor(log2(5^e10)) so that we get at least this many bits; better to
130         // have an additional bit than to not have enough bits.
131         e2 = floor_log2(m10)
132             .wrapping_add(e10 as u32)
133             .wrapping_add(log2_pow5(e10) as u32)
134             .wrapping_sub(f2s::FLOAT_MANTISSA_BITS + 1) as i32;
135 
136         // We now compute [m10 * 10^e10 / 2^e2] = [m10 * 5^e10 / 2^(e2-e10)].
137         // To that end, we use the FLOAT_POW5_SPLIT table.
138         let j = e2
139             .wrapping_sub(e10)
140             .wrapping_sub(ceil_log2_pow5(e10))
141             .wrapping_add(f2s::FLOAT_POW5_BITCOUNT);
142         debug_assert!(j >= 0);
143         m2 = mul_pow5_div_pow2(m10, e10 as u32, j);
144 
145         // We also compute if the result is exact, i.e.,
146         //   [m10 * 10^e10 / 2^e2] == m10 * 10^e10 / 2^e2.
147         // This can only be the case if 2^e2 divides m10 * 10^e10, which in turn
148         // requires that the largest power of 2 that divides m10 + e10 is
149         // greater than e2. If e2 is less than e10, then the result must be
150         // exact. Otherwise we use the existing multiple_of_power_of_2 function.
151         trailing_zeros =
152             e2 < e10 || e2 - e10 < 32 && multiple_of_power_of_2_32(m10, (e2 - e10) as u32);
153     } else {
154         e2 = floor_log2(m10)
155             .wrapping_add(e10 as u32)
156             .wrapping_sub(ceil_log2_pow5(-e10) as u32)
157             .wrapping_sub(f2s::FLOAT_MANTISSA_BITS + 1) as i32;
158 
159         // We now compute [m10 * 10^e10 / 2^e2] = [m10 / (5^(-e10) 2^(e2-e10))].
160         let j = e2
161             .wrapping_sub(e10)
162             .wrapping_add(ceil_log2_pow5(-e10))
163             .wrapping_sub(1)
164             .wrapping_add(f2s::FLOAT_POW5_INV_BITCOUNT);
165         m2 = mul_pow5_inv_div_pow2(m10, -e10 as u32, j);
166 
167         // We also compute if the result is exact, i.e.,
168         //   [m10 / (5^(-e10) 2^(e2-e10))] == m10 / (5^(-e10) 2^(e2-e10))
169         //
170         // If e2-e10 >= 0, we need to check whether (5^(-e10) 2^(e2-e10))
171         // divides m10, which is the case iff pow5(m10) >= -e10 AND pow2(m10) >=
172         // e2-e10.
173         //
174         // If e2-e10 < 0, we have actually computed [m10 * 2^(e10 e2) /
175         // 5^(-e10)] above, and we need to check whether 5^(-e10) divides (m10 *
176         // 2^(e10-e2)), which is the case iff pow5(m10 * 2^(e10-e2)) = pow5(m10)
177         // >= -e10.
178         trailing_zeros = (e2 < e10
179             || (e2 - e10 < 32 && multiple_of_power_of_2_32(m10, (e2 - e10) as u32)))
180             && multiple_of_power_of_5_32(m10, -e10 as u32);
181     }
182 
183     // Compute the final IEEE exponent.
184     let mut ieee_e2 = i32::max(0, e2 + FLOAT_EXPONENT_BIAS as i32 + floor_log2(m2) as i32) as u32;
185 
186     if ieee_e2 > 0xfe {
187         // Final IEEE exponent is larger than the maximum representable; return
188         // +/-Infinity.
189         let ieee = ((signed_m as u32) << (f2s::FLOAT_EXPONENT_BITS + f2s::FLOAT_MANTISSA_BITS))
190             | (0xff_u32 << f2s::FLOAT_MANTISSA_BITS);
191         return Ok(f32::from_bits(ieee));
192     }
193 
194     // We need to figure out how much we need to shift m2. The tricky part is
195     // that we need to take the final IEEE exponent into account, so we need to
196     // reverse the bias and also special-case the value 0.
197     let shift = if ieee_e2 == 0 { 1 } else { ieee_e2 as i32 }
198         .wrapping_sub(e2)
199         .wrapping_sub(FLOAT_EXPONENT_BIAS as i32)
200         .wrapping_sub(f2s::FLOAT_MANTISSA_BITS as i32);
201     debug_assert!(shift >= 0);
202 
203     // We need to round up if the exact value is more than 0.5 above the value
204     // we computed. That's equivalent to checking if the last removed bit was 1
205     // and either the value was not just trailing zeros or the result would
206     // otherwise be odd.
207     //
208     // We need to update trailing_zeros given that we have the exact output
209     // exponent ieee_e2 now.
210     trailing_zeros &= (m2 & ((1_u32 << (shift - 1)) - 1)) == 0;
211     let last_removed_bit = (m2 >> (shift - 1)) & 1;
212     let round_up = last_removed_bit != 0 && (!trailing_zeros || ((m2 >> shift) & 1) != 0);
213 
214     let mut ieee_m2 = (m2 >> shift).wrapping_add(round_up as u32);
215     debug_assert!(ieee_m2 <= 1_u32 << (f2s::FLOAT_MANTISSA_BITS + 1));
216     ieee_m2 &= (1_u32 << f2s::FLOAT_MANTISSA_BITS) - 1;
217     if ieee_m2 == 0 && round_up {
218         // Rounding up may overflow the mantissa.
219         // In this case we move a trailing zero of the mantissa into the
220         // exponent.
221         // Due to how the IEEE represents +/-Infinity, we don't need to check
222         // for overflow here.
223         ieee_e2 += 1;
224     }
225     let ieee = ((((signed_m as u32) << f2s::FLOAT_EXPONENT_BITS) | ieee_e2)
226         << f2s::FLOAT_MANTISSA_BITS)
227         | ieee_m2;
228     Ok(f32::from_bits(ieee))
229 }
230