Skip to content

Commit

Permalink
Merge pull request rust-lang#718 from tgross35/float-trait-refactor
Browse files Browse the repository at this point in the history
Rename Float::repr and Float::from_repr
  • Loading branch information
tgross35 authored Oct 25, 2024
2 parents adaef32 + 64f131a commit 27d64ee
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 72 deletions.
20 changes: 10 additions & 10 deletions src/float/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,26 @@ where
let quiet_bit = implicit_bit >> 1;
let qnan_rep = exponent_mask | quiet_bit;

let mut a_rep = a.repr();
let mut b_rep = b.repr();
let mut a_rep = a.to_bits();
let mut b_rep = b.to_bits();
let a_abs = a_rep & abs_mask;
let b_abs = b_rep & abs_mask;

// Detect if a or b is zero, infinity, or NaN.
if a_abs.wrapping_sub(one) >= inf_rep - one || b_abs.wrapping_sub(one) >= inf_rep - one {
// NaN + anything = qNaN
if a_abs > inf_rep {
return F::from_repr(a_abs | quiet_bit);
return F::from_bits(a_abs | quiet_bit);
}
// anything + NaN = qNaN
if b_abs > inf_rep {
return F::from_repr(b_abs | quiet_bit);
return F::from_bits(b_abs | quiet_bit);
}

if a_abs == inf_rep {
// +/-infinity + -/+infinity = qNaN
if (a.repr() ^ b.repr()) == sign_bit {
return F::from_repr(qnan_rep);
if (a.to_bits() ^ b.to_bits()) == sign_bit {
return F::from_bits(qnan_rep);
} else {
// +/-infinity + anything remaining = +/- infinity
return a;
Expand All @@ -60,7 +60,7 @@ where
if a_abs == MinInt::ZERO {
// but we need to get the sign right for zero + zero
if b_abs == MinInt::ZERO {
return F::from_repr(a.repr() & b.repr());
return F::from_bits(a.to_bits() & b.to_bits());
} else {
return b;
}
Expand Down Expand Up @@ -126,7 +126,7 @@ where
a_significand = a_significand.wrapping_sub(b_significand);
// If a == -b, return +zero.
if a_significand == MinInt::ZERO {
return F::from_repr(MinInt::ZERO);
return F::from_bits(MinInt::ZERO);
}

// If partial cancellation occured, we need to left-shift the result
Expand All @@ -152,7 +152,7 @@ where

// If we have overflowed the type, return +/- infinity:
if a_exponent >= max_exponent as i32 {
return F::from_repr(inf_rep | result_sign);
return F::from_bits(inf_rep | result_sign);
}

if a_exponent <= 0 {
Expand Down Expand Up @@ -185,7 +185,7 @@ where
result += result & one;
}

F::from_repr(result)
F::from_bits(result)
}

intrinsics! {
Expand Down
12 changes: 6 additions & 6 deletions src/float/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ fn cmp<F: Float>(a: F, b: F) -> Result {
let exponent_mask = F::EXPONENT_MASK;
let inf_rep = exponent_mask;

let a_rep = a.repr();
let b_rep = b.repr();
let a_rep = a.to_bits();
let b_rep = b.to_bits();
let a_abs = a_rep & abs_mask;
let b_abs = b_rep & abs_mask;

Expand All @@ -56,8 +56,8 @@ fn cmp<F: Float>(a: F, b: F) -> Result {
return Result::Equal;
}

let a_srep = a.signed_repr();
let b_srep = b.signed_repr();
let a_srep = a.to_bits_signed();
let b_srep = b.to_bits_signed();

// If at least one of a and b is positive, we get the same result comparing
// a and b as signed integers as we would with a fp_ting-point compare.
Expand Down Expand Up @@ -90,8 +90,8 @@ fn unord<F: Float>(a: F, b: F) -> bool {
let exponent_mask = F::EXPONENT_MASK;
let inf_rep = exponent_mask;

let a_rep = a.repr();
let b_rep = b.repr();
let a_rep = a.to_bits();
let b_rep = b.to_bits();
let a_abs = a_rep & abs_mask;
let b_abs = b_rep & abs_mask;

Expand Down
6 changes: 3 additions & 3 deletions src/float/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ where
F::Int: CastInto<U::UnsignedInt>,
u32: CastFrom<F::Int>,
{
float_to_int_inner::<F, U, _, _>(f.repr(), |i: U| i, || U::MAX)
float_to_int_inner::<F, U, _, _>(f.to_bits(), |i: U| i, || U::MAX)
}

/// Generic float to signed int conversions.
Expand All @@ -172,7 +172,7 @@ where
u32: CastFrom<F::Int>,
{
float_to_int_inner::<F, I, _, _>(
f.repr() & !F::SIGN_MASK,
f.to_bits() & !F::SIGN_MASK,
|i: I| if f.is_sign_negative() { -i } else { i },
|| if f.is_sign_negative() { I::MIN } else { I::MAX },
)
Expand Down Expand Up @@ -203,7 +203,7 @@ where
let int_max_exp = F::EXPONENT_BIAS + I::MAX.ilog2() + 1;
let foobar = F::EXPONENT_BIAS + I::UnsignedInt::BITS - 1;

if fbits < F::ONE.repr() {
if fbits < F::ONE.to_bits() {
// < 0 gets rounded to 0
I::ZERO
} else if fbits < F::Int::cast_from(int_max_exp) << F::SIGNIFICAND_BITS {
Expand Down
26 changes: 13 additions & 13 deletions src/float/div.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ where
half_iterations += 1;
}

let a_rep = a.repr();
let b_rep = b.repr();
let a_rep = a.to_bits();
let b_rep = b.to_bits();

// Exponent numeric representationm not accounting for bias
let a_exponent = (a_rep >> significand_bits) & exponent_sat;
Expand All @@ -150,42 +150,42 @@ where

// NaN / anything = qNaN
if a_abs > inf_rep {
return F::from_repr(a_rep | quiet_bit);
return F::from_bits(a_rep | quiet_bit);
}

// anything / NaN = qNaN
if b_abs > inf_rep {
return F::from_repr(b_rep | quiet_bit);
return F::from_bits(b_rep | quiet_bit);
}

if a_abs == inf_rep {
if b_abs == inf_rep {
// infinity / infinity = NaN
return F::from_repr(qnan_rep);
return F::from_bits(qnan_rep);
} else {
// infinity / anything else = +/- infinity
return F::from_repr(a_abs | quotient_sign);
return F::from_bits(a_abs | quotient_sign);
}
}

// anything else / infinity = +/- 0
if b_abs == inf_rep {
return F::from_repr(quotient_sign);
return F::from_bits(quotient_sign);
}

if a_abs == zero {
if b_abs == zero {
// zero / zero = NaN
return F::from_repr(qnan_rep);
return F::from_bits(qnan_rep);
} else {
// zero / anything else = +/- zero
return F::from_repr(quotient_sign);
return F::from_bits(quotient_sign);
}
}

// anything else / zero = +/- infinity
if b_abs == zero {
return F::from_repr(inf_rep | quotient_sign);
return F::from_bits(inf_rep | quotient_sign);
}

// a is denormal. Renormalize it and set the scale to include the necessary exponent
Expand Down Expand Up @@ -463,7 +463,7 @@ where
//
// If we have overflowed the exponent, return infinity
if res_exponent >= i32::cast_from(exponent_sat) {
return F::from_repr(inf_rep | quotient_sign);
return F::from_bits(inf_rep | quotient_sign);
}

// Now, quotient <= the correctly-rounded result
Expand All @@ -476,7 +476,7 @@ where
ret
} else {
if ((significand_bits as i32) + res_exponent) < 0 {
return F::from_repr(quotient_sign);
return F::from_bits(quotient_sign);
}

let ret = quotient.wrapping_shr(u32::cast_from(res_exponent.wrapping_neg()) + 1);
Expand All @@ -501,7 +501,7 @@ where
u8::from(abs_result < inf_rep && residual_lo > (4 + 1).cast() * b_significand).into();
}

F::from_repr(abs_result | quotient_sign)
F::from_bits(abs_result | quotient_sign)
}

/// Calculate the number of iterations required for a float type's precision.
Expand Down
6 changes: 3 additions & 3 deletions src/float/extend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ where

let sign_bits_delta = dst_sign_bits - src_sign_bits;
let exp_bias_delta = dst_exp_bias - src_exp_bias;
let a_abs = a.repr() & src_abs_mask;
let a_abs = a.to_bits() & src_abs_mask;
let mut abs_result = R::Int::ZERO;

if a_abs.wrapping_sub(src_min_normal) < src_infinity.wrapping_sub(src_min_normal) {
Expand Down Expand Up @@ -65,8 +65,8 @@ where
abs_result = (abs_result ^ dst_min_normal) | (bias_dst.wrapping_shl(dst_sign_bits));
}

let sign_result: R::Int = (a.repr() & src_sign_mask).cast();
R::from_repr(abs_result | (sign_result.wrapping_shl(dst_bits - src_bits)))
let sign_result: R::Int = (a.to_bits() & src_sign_mask).cast();
R::from_bits(abs_result | (sign_result.wrapping_shl(dst_bits - src_bits)))
}

intrinsics! {
Expand Down
33 changes: 19 additions & 14 deletions src/float/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ pub(crate) trait Float:
const EXPONENT_MASK: Self::Int;

/// Returns `self` transmuted to `Self::Int`
fn repr(self) -> Self::Int;
fn to_bits(self) -> Self::Int;

/// Returns `self` transmuted to `Self::SignedInt`
fn signed_repr(self) -> Self::SignedInt;
fn to_bits_signed(self) -> Self::SignedInt;

/// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
/// represented in multiple different ways. This method returns `true` if two NaNs are
Expand All @@ -93,10 +93,15 @@ pub(crate) trait Float:
fn imp_frac(self) -> Self::Int;

/// Returns a `Self::Int` transmuted back to `Self`
fn from_repr(a: Self::Int) -> Self;
fn from_bits(a: Self::Int) -> Self;

/// Constructs a `Self` from its parts. Inputs are treated as bits and shifted into position.
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self;
fn from_parts(negative: bool, exponent: Self::Int, significand: Self::Int) -> Self;

fn abs(self) -> Self {
let abs_mask = !Self::SIGN_MASK ;
Self::from_bits(self.to_bits() & abs_mask)
}

/// Returns (normalized exponent, normalized significand)
fn normalize(significand: Self::Int) -> (i32, Self::Int);
Expand Down Expand Up @@ -124,10 +129,10 @@ macro_rules! float_impl {
const IMPLICIT_BIT: Self::Int = 1 << Self::SIGNIFICAND_BITS;
const EXPONENT_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIGNIFICAND_MASK);

fn repr(self) -> Self::Int {
fn to_bits(self) -> Self::Int {
self.to_bits()
}
fn signed_repr(self) -> Self::SignedInt {
fn to_bits_signed(self) -> Self::SignedInt {
self.to_bits() as Self::SignedInt
}
fn eq_repr(self, rhs: Self) -> bool {
Expand All @@ -137,8 +142,8 @@ macro_rules! float_impl {
// necessary builtin (__unordtf2) to test whether `f128` is NaN.
// FIXME(f16_f128): Remove once the nightly toolchain has the __unordtf2 builtin
// x is NaN if all the bits of the exponent are set and the significand is non-0
x.repr() & $ty::EXPONENT_MASK == $ty::EXPONENT_MASK
&& x.repr() & $ty::SIGNIFICAND_MASK != 0
x.to_bits() & $ty::EXPONENT_MASK == $ty::EXPONENT_MASK
&& x.to_bits() & $ty::SIGNIFICAND_MASK != 0
}
#[cfg(not(feature = "mangled-names"))]
fn is_nan(x: $ty) -> bool {
Expand All @@ -147,7 +152,7 @@ macro_rules! float_impl {
if is_nan(self) && is_nan(rhs) {
true
} else {
self.repr() == rhs.repr()
self.to_bits() == rhs.to_bits()
}
}
fn is_sign_negative(self) -> bool {
Expand All @@ -162,12 +167,12 @@ macro_rules! float_impl {
fn imp_frac(self) -> Self::Int {
self.frac() | Self::IMPLICIT_BIT
}
fn from_repr(a: Self::Int) -> Self {
fn from_bits(a: Self::Int) -> Self {
Self::from_bits(a)
}
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
Self::from_repr(
((sign as Self::Int) << (Self::BITS - 1))
fn from_parts(negative: bool, exponent: Self::Int, significand: Self::Int) -> Self {
Self::from_bits(
((negative as Self::Int) << (Self::BITS - 1))
| ((exponent << Self::SIGNIFICAND_BITS) & Self::EXPONENT_MASK)
| (significand & Self::SIGNIFICAND_MASK),
)
Expand All @@ -182,7 +187,7 @@ macro_rules! float_impl {
)
}
fn is_subnormal(self) -> bool {
(self.repr() & Self::EXPONENT_MASK) == Self::Int::ZERO
(self.to_bits() & Self::EXPONENT_MASK) == Self::Int::ZERO
}
}
};
Expand Down
Loading

0 comments on commit 27d64ee

Please sign in to comment.