accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
*/
-use prelude::v1::*;
-
+use num::diy_float::Fp;
use num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
-/// A custom 64-bit floating point type, representing `f * 2^e`.
-#[derive(Copy, Clone, Debug)]
-#[doc(hidden)]
-pub struct Fp {
- /// The integer mantissa.
- pub f: u64,
- /// The exponent in base 2.
- pub e: i16,
-}
-
-impl Fp {
- /// Returns a correctly rounded product of itself and `other`.
- pub fn mul(&self, other: &Fp) -> Fp {
- const MASK: u64 = 0xffffffff;
- let a = self.f >> 32;
- let b = self.f & MASK;
- let c = other.f >> 32;
- let d = other.f & MASK;
- let ac = a * c;
- let bc = b * c;
- let ad = a * d;
- let bd = b * d;
- let tmp = (bd >> 32) + (ad & MASK) + (bc & MASK) + (1 << 31) /* round */;
- let f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32);
- let e = self.e + other.e + 64;
- Fp { f: f, e: e }
- }
-
- /// Normalizes itself so that the resulting mantissa is at least `2^63`.
- pub fn normalize(&self) -> Fp {
- let mut f = self.f;
- let mut e = self.e;
- if f >> (64 - 32) == 0 { f <<= 32; e -= 32; }
- if f >> (64 - 16) == 0 { f <<= 16; e -= 16; }
- if f >> (64 - 8) == 0 { f <<= 8; e -= 8; }
- if f >> (64 - 4) == 0 { f <<= 4; e -= 4; }
- if f >> (64 - 2) == 0 { f <<= 2; e -= 2; }
- if f >> (64 - 1) == 0 { f <<= 1; e -= 1; }
- debug_assert!(f >= (1 >> 63));
- Fp { f: f, e: e }
- }
-
- /// Normalizes itself to have the shared exponent.
- /// It can only decrease the exponent (and thus increase the mantissa).
- pub fn normalize_to(&self, e: i16) -> Fp {
- let edelta = self.e - e;
- assert!(edelta >= 0);
- let edelta = edelta as usize;
- assert_eq!(self.f << edelta >> edelta, self.f);
- Fp { f: self.f << edelta, e: e }
- }
-}
// see the comments in `format_shortest_opt` for the rationale.
#[doc(hidden)] pub const ALPHA: i16 = -60;
// but scaling `max_ten_kappa << e` by 10 can result in overflow.
// thus we are being sloppy here and widen the error range by a factor of 10.
// this will increase the false negative rate, but only very, *very* slightly;
- // it can only matter noticably when the mantissa is bigger than 60 bits.
+ // it can only matter noticeably when the mantissa is bigger than 60 bits.
return possibly_round(buf, 0, exp, limit, v.f / 10, (max_ten_kappa as u64) << e, err << e);
} else if ((exp as i32 - limit as i32) as usize) < buf.len() {
(exp - limit) as usize