//! Many functions in this module only handle normal numbers. The dec2flt routines conservatively
//! take the universally-correct slow path (Algorithm M) for very small and very large numbers.
//! That algorithm needs only next_float() which does handle subnormals and zeros.
-use prelude::v1::*;
use u32;
use cmp::Ordering::{Less, Equal, Greater};
use ops::{Mul, Div, Neg};
pub trait RawFloat : Float + Copy + Debug + LowerExp
+ Mul<Output=Self> + Div<Output=Self> + Neg<Output=Self>
{
+ // suffix of "2" because Float::infinity is deprecated
+ #[allow(deprecated)]
+ fn infinity2() -> Self {
+ Float::infinity()
+ }
+
+ // suffix of "2" because Float::nan is deprecated
+ #[allow(deprecated)]
+ fn nan2() -> Self {
+ Float::nan()
+ }
+
+ // suffix of "2" because Float::zero is deprecated
+ fn zero2() -> Self;
+
+ // suffix of "2" because Float::integer_decode is deprecated
+ #[allow(deprecated)]
+ fn integer_decode2(self) -> (u64, i16, i8) {
+ Float::integer_decode(self)
+ }
+
/// Get the raw binary representation of the float.
fn transmute(self) -> u64;
}
impl RawFloat for f32 {
+ fn zero2() -> Self {
+ 0.0
+ }
+
fn sig_bits() -> u8 {
24
}
}
fn unpack(self) -> Unpacked {
- let (sig, exp, _sig) = self.integer_decode();
+ let (sig, exp, _sig) = self.integer_decode2();
Unpacked::new(sig, exp)
}
impl RawFloat for f64 {
+ fn zero2() -> Self {
+ 0.0
+ }
+
fn sig_bits() -> u8 {
53
}
}
fn unpack(self) -> Unpacked {
- let (sig, exp, _sig) = self.integer_decode();
+ let (sig, exp, _sig) = self.integer_decode2();
Unpacked::new(sig, exp)
}
pub fn next_float<T: RawFloat>(x: T) -> T {
match x.classify() {
Nan => panic!("next_float: argument is NaN"),
- Infinite => T::infinity(),
+ Infinite => T::infinity2(),
// This seems too good to be true, but it works.
// 0.0 is encoded as the all-zero word. Subnormals are 0x000m...m where m is the mantissa.
// In particular, the smallest subnormal is 0x0...01 and the largest is 0x000F...F.