Skip to content

Commit 9837f1e

Browse files
committed
dec2flt: Move internal traits to better locations
`Float` and `FloatExt` are already used by both parsing and printing, so move them out of `dec2flt` to a new module in `num::imp`. `Int` `Cast` have the potential to be used more places in the future, so move them there as well. `Lemire` is the only remaining trait; since it is small, move it into the `dec2flt` root.
1 parent 8ec83c0 commit 9837f1e

File tree

11 files changed

+395
-17
lines changed

11 files changed

+395
-17
lines changed

library/core/src/num/imp/dec2flt/decimal.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//! Representation of a float as the significant digits and exponent.
22
3-
use crate::num::imp::dec2flt;
4-
use dec2flt::float::Lemire;
3+
use dec2flt::Lemire;
54
use dec2flt::fpu::set_precision;
65

6+
use crate::num::imp::dec2flt;
7+
78
const INT_POW10: [u64; 16] = [
89
1,
910
10,

library/core/src/num/imp/dec2flt/lemire.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
//! Implementation of the Eisel-Lemire algorithm.
22
33
use dec2flt::common::BiasedFp;
4-
use dec2flt::float::Float;
54
use dec2flt::table::{LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE};
65

7-
use crate::num::imp::dec2flt;
6+
use crate::num::imp::{Float, dec2flt};
87

98
/// Compute w * 10^q using an extended-precision float representation.
109
///

library/core/src/num/imp/dec2flt/mod.rs

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,24 +88,104 @@
8888
)]
8989

9090
use common::BiasedFp;
91-
use float::{FloatExt, Lemire};
9291
use lemire::compute_float;
9392
use parse::{parse_inf_nan, parse_number};
9493
use slow::parse_long_mantissa;
9594

95+
use crate::f64;
9696
use crate::num::ParseFloatError;
9797
use crate::num::float_parse::FloatErrorKind;
98+
use crate::num::imp::FloatExt;
9899

99100
mod common;
100101
pub mod decimal;
101102
pub mod decimal_seq;
102103
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;
107104
pub mod lemire;
108105
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+
}
109189

110190
#[inline]
111191
pub(super) fn pfe_empty() -> ParseFloatError {

library/core/src/num/imp/dec2flt/parse.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
33
use dec2flt::common::{ByteSlice, is_8digits};
44
use dec2flt::decimal::Decimal;
5-
use dec2flt::float::Float;
65

7-
use crate::num::imp::dec2flt;
6+
use crate::num::imp::{Float, dec2flt};
87

98
const MIN_19DIGIT_INT: u64 = 100_0000_0000_0000_0000;
109

library/core/src/num/imp/dec2flt/slow.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
33
use dec2flt::common::BiasedFp;
44
use dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
5-
use dec2flt::float::Float;
65

7-
use crate::num::imp::dec2flt;
6+
use crate::num::imp::{Float, dec2flt};
87

98
/// Parse the significant digits and biased, binary exponent of a float.
109
///

library/core/src/num/imp/flt2dec/decoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Decodes a floating-point value into individual parts and error ranges.
22
33
use crate::num::FpCategory;
4-
use crate::num::imp::dec2flt::float::FloatExt;
4+
use crate::num::imp::FloatExt;
55

66
/// Decoded unsigned finite value, such that:
77
///

library/core/src/num/imp/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ pub(crate) mod int_log10;
1616
pub(crate) mod int_sqrt;
1717
pub(crate) mod libm;
1818
pub(crate) mod overflow_panic;
19+
mod traits;
20+
21+
pub use traits::{Float, FloatExt, Int};

0 commit comments

Comments
 (0)