Browse Source

bigint: cleanup float conversions

Oliver Middleton 9 years ago
parent
commit
2c235d2dde
1 changed files with 12 additions and 30 deletions
  1. 12 30
      src/bigint.rs

+ 12 - 30
src/bigint.rs

@@ -1178,16 +1178,16 @@ impl ToPrimitive for BigUint {
             0 => Some(f32::zero()),
             1 => Some(self.data[0] as f32),
             len => {
-                // prevent overflow of exponant
+                // this will prevent any overflow of exponent
                 if len > (f32::MAX_EXP as usize) / big_digit::BITS {
                     None
                 } else {
-                    let exponant = (len - 2) * big_digit::BITS;
+                    let exponent = (len - 2) * big_digit::BITS;
                     // we need 25 significant digits, 24 to be stored and 1 for rounding
                     // this gives at least 33 significant digits
                     let mantissa = big_digit::to_doublebigdigit(self.data[len - 1], self.data[len - 2]);
                     // this cast handles rounding
-                    let ret = (mantissa as f32) * 2.0.powi(exponant as i32);
+                    let ret = (mantissa as f32) * 2.0.powi(exponent as i32);
                     if ret.is_infinite() {
                         None
                     } else {
@@ -1206,26 +1206,22 @@ impl ToPrimitive for BigUint {
             1 => Some(self.data[0] as f64),
             2 => Some(big_digit::to_doublebigdigit(self.data[1], self.data[0]) as f64),
             len => {
-                // this will prevent any overflow of exponant
+                // this will prevent any overflow of exponent
                 if len > (f64::MAX_EXP as usize) / big_digit::BITS {
                     None
                 } else {
-                    let mut exponant = (len - 2) * big_digit::BITS;
+                    let mut exponent = (len - 2) * big_digit::BITS;
                     let mut mantissa = big_digit::to_doublebigdigit(self.data[len - 1], self.data[len - 2]);
                     // we need at least 54 significant bit digits, 53 to be stored and 1 for rounding
-                    // so we take enough from the next BigDigit to make it up if needed
-                    let needed = (f64::MANTISSA_DIGITS as usize) + 1;
-                    let bits = (2 * big_digit::BITS) - (mantissa.leading_zeros() as usize);
-                    if needed > bits {
-                        let diff = needed - bits;
-                        mantissa <<= diff;
-                        exponant -= diff;
-                        let mut x = self.data[len - 3];
-                        x >>= big_digit::BITS - diff;
-                        mantissa |= x as u64;
+                    // so we take enough from the next BigDigit to make it up to 64
+                    let shift = mantissa.leading_zeros() as usize;
+                    if shift > 0 {
+                        mantissa <<= shift;
+                        mantissa |= self.data[len - 3] as u64 >> (big_digit::BITS - shift);
+                        exponent -= shift;
                     }
                     // this cast handles rounding
-                    let ret = (mantissa as f64) * 2.0.powi(exponant as i32);
+                    let ret = (mantissa as f64) * 2.0.powi(exponent as i32);
                     if ret.is_infinite() {
                         None
                     } else {
@@ -1252,11 +1248,6 @@ impl FromPrimitive for BigUint {
         Some(BigUint::from(n))
     }
 
-    #[inline]
-    fn from_f32(n: f32) -> Option<BigUint> {
-        BigUint::from_f64(n as f64)
-    }
-
     #[inline]
     fn from_f64(mut n: f64) -> Option<BigUint> {
         // handle NAN, INFINITY, NEG_INFINITY
@@ -2250,15 +2241,6 @@ impl FromPrimitive for BigInt {
         Some(BigInt::from(n))
     }
 
-    #[inline]
-    fn from_f32(n: f32) -> Option<BigInt> {
-        if n >= 0.0 {
-            BigUint::from_f32(n).map(|x| BigInt::from_biguint(Plus, x))
-        } else {
-            BigUint::from_f32(-n).map(|x| BigInt::from_biguint(Minus, x))
-        }
-    }
-
     #[inline]
     fn from_f64(n: f64) -> Option<BigInt> {
         if n >= 0.0 {