Add floating point deconstruction helpers
This commit is contained in:
parent
cab88e6133
commit
58e89b3024
@ -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;
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user