Skip to content

Commit

Permalink
Remove the FloatDivision trait
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross35 committed Aug 19, 2024
1 parent d664c77 commit 492bc0b
Showing 1 changed file with 18 additions and 44 deletions.
62 changes: 18 additions & 44 deletions src/float/div.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,32 +116,6 @@ mod fmt {
impl Display for i128 {}
}

macro_rules! guess {
($ty:ty) => {
const { (C_U128 >> (u128::BITS - <$ty>::BITS)) as $ty }
};
}

const C_U128: u128 = 0x7504f333f9de6108b2fb1366eaa6a542;

// /// C is (3/4 + 1/sqrt(2)) - 1 truncated to W0 fractional bits as UQ0.HW
// /// with W0 being either 16 or 32 and W0 <= HW.
// /// That is, C is the aforementioned 3/4 + 1/sqrt(2) constant (from which
// /// b/2 is subtracted to obtain x0) wrapped to [0, 1) range.
// macro_rules! half_width_c {
// ($ty:ty) => {
// const { (C_U128 >> (u128::BITS - <$ty>::BITS)) as $ty }
// };
// }

/// Type-specific configuration used for float division
trait FloatDivision: Float
where
Self::Int: DInt,
{
const C_HW: HalfRep<Self>;
}

/// Calculate the number of iterations required to get needed precision of a float type.
///
/// This returns `(h, f)` where `h` is the number of iterations to be donei using integers
Expand Down Expand Up @@ -205,27 +179,22 @@ const fn reciprocal_precision<F: Float>() -> u16 {
}
}

impl FloatDivision for f32 {
/// Use 16-bit initial estimation in case we are using half-width iterations
/// for float32 division. This is expected to be useful for some 16-bit
/// targets. Not used by default as it requires performing more work during
/// rounding and would hardly help on regular 32- or 64-bit targets.
const C_HW: HalfRep<Self> = guess!(HalfRep<Self>);
}

impl FloatDivision for f64 {
/// HW is at least 32. Shifting into the highest bits if needed.
const C_HW: HalfRep<Self> = guess!(HalfRep<Self>);
}
/// C is (3/4 + 1/sqrt(2)) - 1 truncated to W0 fractional bits as UQ0.HW
/// with W0 being either 16 or 32 and W0 <= HW.
/// That is, C is the aforementioned 3/4 + 1/sqrt(2) constant (from which
/// b/2 is subtracted to obtain x0) wrapped to [0, 1) range.
fn c_hw<F: Float>() -> HalfRep<F>
where
F::Int: DInt,
u128: CastInto<HalfRep<F>>,
{
const C_U128: u128 = 0x7504f333f9de6108b2fb1366eaa6a542;

#[cfg(not(feature = "no-f16-f128"))]
impl FloatDivision for f128 {
const C_HW: HalfRep<Self> = guess!(HalfRep<Self>);
const { C_U128 >> (u128::BITS - <HalfRep<F>>::BITS) }.cast()
}

fn div<F>(a: F, b: F) -> F
fn div<F: Float>(a: F, b: F) -> F
where
F: FloatDivision,
F::Int: CastInto<u32>,
F::Int: CastFrom<u32>,
F::Int: CastInto<i32>,
Expand All @@ -248,6 +217,7 @@ where
u64: CastInto<F::Int>,
u64: CastInto<HalfRep<F>>,
u128: CastInto<F::Int>,
u128: CastInto<HalfRep<F>>,

// TODO: remove
F::Int: fmt::LowerHex,
Expand Down Expand Up @@ -418,7 +388,11 @@ where
// with W0 being either 16 or 32 and W0 <= HW.
// That is, C is the aforementioned 3/4 + 1/sqrt(2) constant (from which
// b/2 is subtracted to obtain x0) wrapped to [0, 1) range.
let c_hw = F::C_HW;
let c_hw = c_hw::<F>();

// guess!(HalfRep<F>);

// F::C_HW;

// Check that the top bit is set, i.e. value is within `[1, 2)`.
debug_assert!(b_uq1_hw & one_hw << (HalfRep::<F>::BITS - 1) > zero_hw);
Expand Down

0 comments on commit 492bc0b

Please sign in to comment.