1 // Adapted from https://github.com/Alexhuszagh/rust-lexical.
2 
3 //! Utilities to calculate exponents.
4 
5 /// Convert usize into i32 without overflow.
6 ///
7 /// This is needed to ensure when adjusting the exponent relative to
8 /// the mantissa we do not overflow for comically-long exponents.
9 #[inline]
into_i32(value: usize) -> i3210 fn into_i32(value: usize) -> i32 {
11     if value > i32::max_value() as usize {
12         i32::max_value()
13     } else {
14         value as i32
15     }
16 }
17 
18 // EXPONENT CALCULATION
19 
20 // Calculate the scientific notation exponent without overflow.
21 //
22 // For example, 0.1 would be -1, and 10 would be 1 in base 10.
23 #[inline]
scientific_exponent( exponent: i32, integer_digits: usize, fraction_start: usize, ) -> i3224 pub(crate) fn scientific_exponent(
25     exponent: i32,
26     integer_digits: usize,
27     fraction_start: usize,
28 ) -> i32 {
29     if integer_digits == 0 {
30         let fraction_start = into_i32(fraction_start);
31         exponent.saturating_sub(fraction_start).saturating_sub(1)
32     } else {
33         let integer_shift = into_i32(integer_digits - 1);
34         exponent.saturating_add(integer_shift)
35     }
36 }
37 
38 // Calculate the mantissa exponent without overflow.
39 //
40 // Remove the number of digits that contributed to the mantissa past
41 // the dot, and add the number of truncated digits from the mantissa,
42 // to calculate the scaling factor for the mantissa from a raw exponent.
43 #[inline]
mantissa_exponent(exponent: i32, fraction_digits: usize, truncated: usize) -> i3244 pub(crate) fn mantissa_exponent(exponent: i32, fraction_digits: usize, truncated: usize) -> i32 {
45     if fraction_digits > truncated {
46         exponent.saturating_sub(into_i32(fraction_digits - truncated))
47     } else {
48         exponent.saturating_add(into_i32(truncated - fraction_digits))
49     }
50 }
51