소스 검색

Add floating point deconstruction helpers

Matt Ickstadt 8 년 전
부모
커밋
58e89b3024
2개의 변경된 파일39개의 추가작업 그리고 1개의 파일을 삭제
  1. 1 1
      src/float/add.rs
  2. 38 0
      src/float/mod.rs

+ 1 - 1
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;

+ 38 - 0
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());