瀏覽代碼

Introduce a float_impl! macro to avoid duplication

est31 7 年之前
父節點
當前提交
46cfa05650
共有 1 個文件被更改,包括 39 次插入67 次删除
  1. 39 67
      src/float/mod.rs

+ 39 - 67
src/float/mod.rs

@@ -60,73 +60,45 @@ pub trait Float: Sized + Copy {
 
 // FIXME: Some of this can be removed if RFC Issue #1424 is resolved
 //        https://github.com/rust-lang/rfcs/issues/1424
-impl Float for f32 {
-    type Int = u32;
-    const BITS: u32 = 32;
-    const SIGNIFICAND_BITS: u32 = 23;
-
-    const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
-    const SIGNIFICAND_MASK: Self::Int = (1 << Self::SIGNIFICAND_BITS) - 1;
-    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 {
-        unsafe { mem::transmute(self) }
-    }
-    #[cfg(test)]
-    fn eq_repr(self, rhs: Self) -> bool {
-        if self.is_nan() && rhs.is_nan() {
-            true
-        } else {
-            self.repr() == rhs.repr()
-        }
-    }
-    fn from_repr(a: Self::Int) -> Self {
-        unsafe { mem::transmute(a) }
-    }
-    fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
-        Self::from_repr(((sign as Self::Int) << (Self::BITS - 1)) |
-            ((exponent << Self::SIGNIFICAND_BITS) & Self::EXPONENT_MASK) |
-            (significand & Self::SIGNIFICAND_MASK))
-    }
-    fn normalize(significand: Self::Int) -> (i32, Self::Int) {
-        let shift = significand.leading_zeros()
-            .wrapping_sub((1u32 << Self::SIGNIFICAND_BITS).leading_zeros());
-        (1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
-    }
-}
-impl Float for f64 {
-    type Int = u64;
-    const BITS: u32 = 64;
-    const SIGNIFICAND_BITS: u32 = 52;
-
-    const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
-    const SIGNIFICAND_MASK: Self::Int = (1 << Self::SIGNIFICAND_BITS) - 1;
-    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 {
-        unsafe { mem::transmute(self) }
-    }
-    #[cfg(test)]
-    fn eq_repr(self, rhs: Self) -> bool {
-        if self.is_nan() && rhs.is_nan() {
-            true
-        } else {
-            self.repr() == rhs.repr()
+macro_rules! float_impl {
+    ($ty:ident, $ity:ident, $bits:expr, $significand_bits:expr) => {
+        impl Float for $ty {
+            type Int = $ity;
+            const BITS: u32 = $bits;
+            const SIGNIFICAND_BITS: u32 = $significand_bits;
+
+            const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
+            const SIGNIFICAND_MASK: Self::Int = (1 << Self::SIGNIFICAND_BITS) - 1;
+            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 {
+                unsafe { mem::transmute(self) }
+            }
+            #[cfg(test)]
+            fn eq_repr(self, rhs: Self) -> bool {
+                if self.is_nan() && rhs.is_nan() {
+                    true
+                } else {
+                    self.repr() == rhs.repr()
+                }
+            }
+            fn from_repr(a: Self::Int) -> Self {
+                unsafe { mem::transmute(a) }
+            }
+            fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
+                Self::from_repr(((sign as Self::Int) << (Self::BITS - 1)) |
+                    ((exponent << Self::SIGNIFICAND_BITS) & Self::EXPONENT_MASK) |
+                    (significand & Self::SIGNIFICAND_MASK))
+            }
+            fn normalize(significand: Self::Int) -> (i32, Self::Int) {
+                let shift = significand.leading_zeros()
+                    .wrapping_sub((Self::Int::ONE << Self::SIGNIFICAND_BITS).leading_zeros());
+                (1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
+            }
         }
     }
-    fn from_repr(a: Self::Int) -> Self {
-        unsafe { mem::transmute(a) }
-    }
-    fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
-        Self::from_repr(((sign as Self::Int) << (Self::BITS - 1)) |
-            ((exponent << Self::SIGNIFICAND_BITS) & Self::EXPONENT_MASK) |
-            (significand & Self::SIGNIFICAND_MASK))
-    }
-    fn normalize(significand: Self::Int) -> (i32, Self::Int) {
-        let shift = significand.leading_zeros()
-            .wrapping_sub((1u64 << Self::SIGNIFICAND_BITS).leading_zeros());
-        (1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
-    }
 }
+
+float_impl!(f32, u32, 32, 23);
+float_impl!(f64, u64, 64, 52);