From 58e89b30241038c03234b3ed91179559e70e1920 Mon Sep 17 00:00:00 2001 From: Matt Ickstadt Date: Thu, 29 Sep 2016 20:48:20 -0500 Subject: [PATCH] Add floating point deconstruction helpers --- src/float/add.rs | 2 +- src/float/mod.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/float/add.rs b/src/float/add.rs index 7707850..a462168 100644 --- a/src/float/add.rs +++ b/src/float/add.rs @@ -14,7 +14,7 @@ macro_rules! add { let bits = Wrapping(<$ty>::bits() as <$ty as Float>::Int); let significand_bits = Wrapping(<$ty>::significand_bits() as <$ty as Float>::Int); - let exponent_bits = bits - significand_bits - one; + let exponent_bits = Wrapping(<$ty>::exponent_bits() as <$ty as Float>::Int); let max_exponent = (one << exponent_bits.0 as usize) - one; let implicit_bit = one << significand_bits.0 as usize; diff --git a/src/float/mod.rs b/src/float/mod.rs index cee2b73..a44faad 100644 --- a/src/float/mod.rs +++ b/src/float/mod.rs @@ -10,6 +10,9 @@ pub trait Float: Sized + Copy { /// Returns the bitwidth of the float type fn bits() -> u32; + /// Returns the bitwidth of the exponent + fn exponent_bits() -> u32; + /// Returns the bitwidth of the significand fn significand_bits() -> u32; @@ -25,6 +28,15 @@ pub trait Float: Sized + Copy { /// Returns a `Self::Int` transmuted back to `Self` fn from_repr(a: Self::Int) -> Self; + /// Returns the sign bit of `self` + fn sign(self) -> bool; + + /// Returns the exponent portion of `self`, shifted to the right + fn exponent(self) -> Self::Int; + + /// Returns the significand portion of `self` + fn significand(self) -> Self::Int; + /// Returns (normalized exponent, normalized significand) fn normalize(significand: Self::Int) -> (i32, Self::Int); } @@ -34,6 +46,9 @@ impl Float for f32 { fn bits() -> u32 { 32 } + fn exponent_bits() -> u32 { + 8 + } fn significand_bits() -> u32 { 23 } @@ -51,6 +66,16 @@ impl Float for f32 { fn from_repr(a: Self::Int) -> Self { unsafe { mem::transmute(a) } } + fn sign(self) -> bool { + (self.repr() & 1 << Self::bits()) != 0 + } + fn exponent(self) -> Self::Int { + self.repr() >> Self::significand_bits() + & ((1 << Self::exponent_bits()) - 1) + } + fn significand(self) -> Self::Int { + self.repr() & ((1 << Self::significand_bits()) - 1) + } fn normalize(significand: Self::Int) -> (i32, Self::Int) { let shift = significand.leading_zeros() .wrapping_sub((1u32 << Self::significand_bits()).leading_zeros()); @@ -62,6 +87,9 @@ impl Float for f64 { fn bits() -> u32 { 64 } + fn exponent_bits() -> u32 { + 11 + } fn significand_bits() -> u32 { 52 } @@ -79,6 +107,16 @@ impl Float for f64 { fn from_repr(a: Self::Int) -> Self { unsafe { mem::transmute(a) } } + fn sign(self) -> bool { + (self.repr() & 1 << Self::bits()) != 0 + } + fn exponent(self) -> Self::Int { + self.repr() >> Self::significand_bits() + & ((1 << Self::exponent_bits()) - 1) + } + fn significand(self) -> Self::Int { + self.repr() & ((1 << Self::significand_bits()) - 1) + } fn normalize(significand: Self::Int) -> (i32, Self::Int) { let shift = significand.leading_zeros() .wrapping_sub((1u64 << Self::significand_bits()).leading_zeros());