diff --git a/src/float/add.rs b/src/float/add.rs index bceef7b0..ecb96264 100644 --- a/src/float/add.rs +++ b/src/float/add.rs @@ -25,8 +25,8 @@ 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; @@ -34,17 +34,17 @@ where 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; @@ -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; } @@ -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 @@ -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 { @@ -185,7 +185,7 @@ where result += result & one; } - F::from_repr(result) + F::from_bits(result) } intrinsics! { diff --git a/src/float/cmp.rs b/src/float/cmp.rs index bb7d4b49..8b97a0b5 100644 --- a/src/float/cmp.rs +++ b/src/float/cmp.rs @@ -41,8 +41,8 @@ fn cmp(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; @@ -56,8 +56,8 @@ fn cmp(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. @@ -90,8 +90,8 @@ fn unord(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; diff --git a/src/float/conv.rs b/src/float/conv.rs index d275f982..e86fee6d 100644 --- a/src/float/conv.rs +++ b/src/float/conv.rs @@ -158,7 +158,7 @@ where F::Int: CastInto, u32: CastFrom, { - float_to_int_inner::(f.repr(), |i: U| i, || U::MAX) + float_to_int_inner::(f.to_bits(), |i: U| i, || U::MAX) } /// Generic float to signed int conversions. @@ -172,7 +172,7 @@ where u32: CastFrom, { float_to_int_inner::( - 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 }, ) @@ -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 { diff --git a/src/float/div.rs b/src/float/div.rs index f125771a..4b3f97c3 100644 --- a/src/float/div.rs +++ b/src/float/div.rs @@ -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; @@ -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 @@ -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 @@ -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); @@ -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. diff --git a/src/float/extend.rs b/src/float/extend.rs index 997475c8..2ec79070 100644 --- a/src/float/extend.rs +++ b/src/float/extend.rs @@ -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) { @@ -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! { diff --git a/src/float/mod.rs b/src/float/mod.rs index 704bba0c..af839864 100644 --- a/src/float/mod.rs +++ b/src/float/mod.rs @@ -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 @@ -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); @@ -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 { @@ -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 { @@ -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 { @@ -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), ) @@ -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 } } }; diff --git a/src/float/mul.rs b/src/float/mul.rs index a4c69ea8..77a271d6 100644 --- a/src/float/mul.rs +++ b/src/float/mul.rs @@ -28,8 +28,8 @@ where let qnan_rep = exponent_mask | quiet_bit; let exponent_bits = F::EXPONENT_BITS; - let a_rep = a.repr(); - let b_rep = b.repr(); + let a_rep = a.to_bits(); + let b_rep = b.to_bits(); let a_exponent = (a_rep >> significand_bits) & max_exponent.cast(); let b_exponent = (b_rep >> significand_bits) & max_exponent.cast(); @@ -48,41 +48,41 @@ 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 != zero { // infinity * non-zero = +/- infinity - return F::from_repr(a_abs | product_sign); + return F::from_bits(a_abs | product_sign); } else { // infinity * zero = NaN - return F::from_repr(qnan_rep); + return F::from_bits(qnan_rep); } } if b_abs == inf_rep { if a_abs != zero { // infinity * non-zero = +/- infinity - return F::from_repr(b_abs | product_sign); + return F::from_bits(b_abs | product_sign); } else { // infinity * zero = NaN - return F::from_repr(qnan_rep); + return F::from_bits(qnan_rep); } } // zero * anything = +/- zero if a_abs == zero { - return F::from_repr(product_sign); + return F::from_bits(product_sign); } // anything * zero = +/- zero if b_abs == zero { - return F::from_repr(product_sign); + return F::from_bits(product_sign); } // one or both of a or b is denormal, the other (if applicable) is a @@ -133,7 +133,7 @@ where // If we have overflowed the type, return +/- infinity. if product_exponent >= max_exponent as i32 { - return F::from_repr(inf_rep | product_sign); + return F::from_bits(inf_rep | product_sign); } if product_exponent <= 0 { @@ -145,7 +145,7 @@ where // simplify the shift logic. let shift = one.wrapping_sub(product_exponent.cast()).cast(); if shift >= bits { - return F::from_repr(product_sign); + return F::from_bits(product_sign); } // Otherwise, shift the significand of the result so that the round @@ -176,7 +176,7 @@ where product_high += product_high & one; } - F::from_repr(product_high) + F::from_bits(product_high) } intrinsics! { diff --git a/src/float/sub.rs b/src/float/sub.rs index 7e8a8945..175b3a16 100644 --- a/src/float/sub.rs +++ b/src/float/sub.rs @@ -4,13 +4,13 @@ intrinsics! { #[avr_skip] #[arm_aeabi_alias = __aeabi_fsub] pub extern "C" fn __subsf3(a: f32, b: f32) -> f32 { - crate::float::add::__addsf3(a, f32::from_repr(b.repr() ^ f32::SIGN_MASK)) + crate::float::add::__addsf3(a, f32::from_bits(b.to_bits() ^ f32::SIGN_MASK)) } #[avr_skip] #[arm_aeabi_alias = __aeabi_dsub] pub extern "C" fn __subdf3(a: f64, b: f64) -> f64 { - crate::float::add::__adddf3(a, f64::from_repr(b.repr() ^ f64::SIGN_MASK)) + crate::float::add::__adddf3(a, f64::from_bits(b.to_bits() ^ f64::SIGN_MASK)) } #[ppc_alias = __subkf3] @@ -21,6 +21,6 @@ intrinsics! { #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] use crate::float::add::__addtf3; - __addtf3(a, f128::from_repr(b.repr() ^ f128::SIGN_MASK)) + __addtf3(a, f128::from_bits(b.to_bits() ^ f128::SIGN_MASK)) } } diff --git a/src/float/trunc.rs b/src/float/trunc.rs index a25b6eab..6fe44f50 100644 --- a/src/float/trunc.rs +++ b/src/float/trunc.rs @@ -7,7 +7,6 @@ where F::Int: CastInto, u64: CastInto, u32: CastInto, - R::Int: CastInto, u32: CastInto, F::Int: CastInto, @@ -43,8 +42,8 @@ where let sign_bits_delta = F::SIGNIFICAND_BITS - R::SIGNIFICAND_BITS; // Break a into a sign and representation of the absolute value. - let a_abs = a.repr() & src_abs_mask; - let sign = a.repr() & src_sign_mask; + let a_abs = a.to_bits() & src_abs_mask; + let sign = a.to_bits() & src_sign_mask; let mut abs_result: R::Int; if a_abs.wrapping_sub(underflow) < a_abs.wrapping_sub(overflow) { @@ -87,7 +86,7 @@ where let a_exp: u32 = (a_abs >> F::SIGNIFICAND_BITS).cast(); let shift = src_exp_bias - dst_exp_bias - a_exp + 1; - let significand = (a.repr() & src_significand_mask) | src_min_normal; + let significand = (a.to_bits() & src_significand_mask) | src_min_normal; // Right shift by the denormalization amount with sticky. if shift > F::SIGNIFICAND_BITS { @@ -114,7 +113,7 @@ where } // Apply the signbit to the absolute value. - R::from_repr(abs_result | sign.wrapping_shr(src_bits - dst_bits).cast()) + R::from_bits(abs_result | sign.wrapping_shr(src_bits - dst_bits).cast()) } intrinsics! { diff --git a/testcrate/src/lib.rs b/testcrate/src/lib.rs index cc9e7393..58419bf1 100644 --- a/testcrate/src/lib.rs +++ b/testcrate/src/lib.rs @@ -190,7 +190,7 @@ fn fuzz_float_step(rng: &mut Xoshiro128StarStar, f: &mut F) { let tmp = ones.wrapping_shr(r0); (tmp.wrapping_shl(r1) | tmp.wrapping_shr(F::EXPONENT_BITS - r1)) & ones }; - let mut exp = (f.repr() & F::EXPONENT_MASK) >> F::SIGNIFICAND_BITS; + let mut exp = (f.to_bits() & F::EXPONENT_MASK) >> F::SIGNIFICAND_BITS; match (rng32 >> 9) % 4 { 0 => exp |= mask, 1 => exp &= mask, @@ -198,7 +198,7 @@ fn fuzz_float_step(rng: &mut Xoshiro128StarStar, f: &mut F) { } // significand fuzzing - let mut sig = f.repr() & F::SIGNIFICAND_MASK; + let mut sig = f.to_bits() & F::SIGNIFICAND_MASK; fuzz_step(rng, &mut sig); sig &= F::SIGNIFICAND_MASK;