|
88 | 88 | )] |
89 | 89 |
|
90 | 90 | use common::BiasedFp; |
91 | | -use float::{FloatExt, Lemire}; |
92 | 91 | use lemire::compute_float; |
93 | 92 | use parse::{parse_inf_nan, parse_number}; |
94 | 93 | use slow::parse_long_mantissa; |
95 | 94 |
|
| 95 | +use crate::f64; |
96 | 96 | use crate::num::ParseFloatError; |
97 | 97 | use crate::num::float_parse::FloatErrorKind; |
| 98 | +use crate::num::imp::FloatExt; |
98 | 99 |
|
99 | 100 | mod common; |
100 | 101 | pub mod decimal; |
101 | 102 | pub mod decimal_seq; |
102 | 103 | mod fpu; |
103 | | -mod slow; |
104 | | -mod table; |
105 | | -// float is used in flt2dec, and all are used in unit tests. |
106 | | -pub mod float; |
107 | 104 | pub mod lemire; |
108 | 105 | pub mod parse; |
| 106 | +mod slow; |
| 107 | +mod table; |
| 108 | + |
| 109 | +/// Extension to `Float` that are necessary for parsing using the Lemire method. |
| 110 | +/// |
| 111 | +/// See the parent module's doc comment for why this is necessary. |
| 112 | +/// |
| 113 | +/// Not intended for use outside of the `dec2flt` module. |
| 114 | +#[doc(hidden)] |
| 115 | +pub trait Lemire: FloatExt { |
| 116 | + /// Maximum exponent for a fast path case, or `⌊(SIG_BITS+1)/log2(5)⌋` |
| 117 | + // assuming FLT_EVAL_METHOD = 0 |
| 118 | + const MAX_EXPONENT_FAST_PATH: i64 = { |
| 119 | + let log2_5 = f64::consts::LOG2_10 - 1.0; |
| 120 | + (Self::SIG_TOTAL_BITS as f64 / log2_5) as i64 |
| 121 | + }; |
| 122 | + |
| 123 | + /// Minimum exponent for a fast path case, or `-⌊(SIG_BITS+1)/log2(5)⌋` |
| 124 | + const MIN_EXPONENT_FAST_PATH: i64 = -Self::MAX_EXPONENT_FAST_PATH; |
| 125 | + |
| 126 | + /// Maximum exponent that can be represented for a disguised-fast path case. |
| 127 | + /// This is `MAX_EXPONENT_FAST_PATH + ⌊(SIG_BITS+1)/log2(10)⌋` |
| 128 | + const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = |
| 129 | + Self::MAX_EXPONENT_FAST_PATH + (Self::SIG_TOTAL_BITS as f64 / f64::consts::LOG2_10) as i64; |
| 130 | + |
| 131 | + /// Maximum mantissa for the fast-path (`1 << 53` for f64). |
| 132 | + const MAX_MANTISSA_FAST_PATH: u64 = 1 << Self::SIG_TOTAL_BITS; |
| 133 | + |
| 134 | + /// Gets a small power-of-ten for fast-path multiplication. |
| 135 | + fn pow10_fast_path(exponent: usize) -> Self; |
| 136 | + |
| 137 | + /// Converts integer into float through an as cast. |
| 138 | + /// This is only called in the fast-path algorithm, and therefore |
| 139 | + /// will not lose precision, since the value will always have |
| 140 | + /// only if the value is <= Self::MAX_MANTISSA_FAST_PATH. |
| 141 | + fn from_u64(v: u64) -> Self; |
| 142 | +} |
| 143 | + |
| 144 | +#[cfg(target_has_reliable_f16)] |
| 145 | +impl Lemire for f16 { |
| 146 | + fn pow10_fast_path(exponent: usize) -> Self { |
| 147 | + #[allow(clippy::use_self)] |
| 148 | + const TABLE: [f16; 8] = [1e0, 1e1, 1e2, 1e3, 1e4, 0.0, 0.0, 0.]; |
| 149 | + TABLE[exponent & 7] |
| 150 | + } |
| 151 | + |
| 152 | + #[inline] |
| 153 | + fn from_u64(v: u64) -> Self { |
| 154 | + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); |
| 155 | + v as _ |
| 156 | + } |
| 157 | +} |
| 158 | + |
| 159 | +impl Lemire for f32 { |
| 160 | + fn pow10_fast_path(exponent: usize) -> Self { |
| 161 | + #[allow(clippy::use_self)] |
| 162 | + const TABLE: [f32; 16] = |
| 163 | + [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 0., 0., 0., 0., 0.]; |
| 164 | + TABLE[exponent & 15] |
| 165 | + } |
| 166 | + |
| 167 | + #[inline] |
| 168 | + fn from_u64(v: u64) -> Self { |
| 169 | + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); |
| 170 | + v as _ |
| 171 | + } |
| 172 | +} |
| 173 | + |
| 174 | +impl Lemire for f64 { |
| 175 | + fn pow10_fast_path(exponent: usize) -> Self { |
| 176 | + const TABLE: [f64; 32] = [ |
| 177 | + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, |
| 178 | + 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 0., 0., 0., 0., 0., 0., 0., 0., 0., |
| 179 | + ]; |
| 180 | + TABLE[exponent & 31] |
| 181 | + } |
| 182 | + |
| 183 | + #[inline] |
| 184 | + fn from_u64(v: u64) -> Self { |
| 185 | + debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH); |
| 186 | + v as _ |
| 187 | + } |
| 188 | +} |
109 | 189 |
|
110 | 190 | #[inline] |
111 | 191 | pub(super) fn pfe_empty() -> ParseFloatError { |
|
0 commit comments