pub trait Ieee754: Copy + PartialEq + PartialOrd {
type Bits: Bits;
type Exponent;
type RawExponent;
type Significand;
fn upto(self, lim: Self) -> Iter<Self> ⓘ;
fn next(self) -> Self;
fn ulp(self) -> Option<Self>;
fn prev(self) -> Self;
fn bits(self) -> Self::Bits;
fn from_bits(x: Self::Bits) -> Self;
fn exponent_bias() -> Self::Exponent;
fn decompose_raw(self) -> (bool, Self::RawExponent, Self::Significand);
fn recompose_raw(
sign: bool,
expn: Self::RawExponent,
signif: Self::Significand
) -> Self;
fn decompose(self) -> (bool, Self::Exponent, Self::Significand);
fn recompose(
sign: bool,
expn: Self::Exponent,
signif: Self::Significand
) -> Self;
fn total_cmp(&self, other: &Self) -> Ordering;
}
Expand description
Types that are IEEE754 floating point numbers.
Required Associated Types§
sourcetype RawExponent
type RawExponent
A type large enough to store the raw exponent (i.e. with the bias).
sourcetype Significand
type Significand
A type large enough to store the significand of Self
.
Required Methods§
sourcefn upto(self, lim: Self) -> Iter<Self> ⓘ
fn upto(self, lim: Self) -> Iter<Self> ⓘ
Iterate over each value of Self
in [self, lim]
.
The returned iterator will include subnormal numbers, and will
only include one of -0.0
and 0.0
.
Panics
Panics if self > lim
, or if either are NaN.
Examples
use ieee754::Ieee754;
// there are 840 single-precision floats in between 1.0 and 1.0001
// (inclusive).
assert_eq!(1_f32.upto(1.0001).count(), 840);
sourcefn next(self) -> Self
fn next(self) -> Self
Return the next value after self
.
Calling this on NaN or positive infinity will yield nonsense.
Examples
use ieee754::Ieee754;
let x: f32 = 1.0;
assert_eq!(x.next(), 1.000000119209);
sourcefn ulp(self) -> Option<Self>
fn ulp(self) -> Option<Self>
Return the unit-in-the-last-place ulp of self
. That is,
x.abs().next() - x.abs()
, but handling overflow properly.
Returns None
if self
is not finite.
sourcefn prev(self) -> Self
fn prev(self) -> Self
Return the previous value before self
.
Calling this on NaN or negative infinity will yield nonsense.
Examples
use ieee754::Ieee754;
let x: f32 = 1.0;
assert_eq!(x.prev(), 0.99999995);
sourcefn bits(self) -> Self::Bits
fn bits(self) -> Self::Bits
View self
as a collection of bits.
Examples
use ieee754::Ieee754;
let x: f32 = 1.0;
assert_eq!(x.bits(), 0x3f80_0000);
sourcefn from_bits(x: Self::Bits) -> Self
fn from_bits(x: Self::Bits) -> Self
View a collections of bits as a floating point number.
Examples
use ieee754::Ieee754;
let float: f32 = Ieee754::from_bits(0xbf80_0000);
assert_eq!(float, -1.0);
sourcefn exponent_bias() -> Self::Exponent
fn exponent_bias() -> Self::Exponent
Get the bias of the stored exponent.
Examples
use ieee754::Ieee754;
assert_eq!(f32::exponent_bias(), 127);
assert_eq!(f64::exponent_bias(), 1023);
sourcefn decompose_raw(self) -> (bool, Self::RawExponent, Self::Significand)
fn decompose_raw(self) -> (bool, Self::RawExponent, Self::Significand)
Break self
into the three constituent parts of an IEEE754 float.
The exponent returned is the raw bits, use exponent_bias
to
compute the offset required or use decompose
to obtain this
in precomputed form.
Examples
Single precision:
use ieee754::Ieee754;
assert_eq!(1_f32.decompose_raw(), (false, 127, 0));
assert_eq!(1234.567_f32.decompose_raw(), (false, 137, 0x1a5225));
assert_eq!((-0.525_f32).decompose_raw(), (true, 126, 0x66666));
assert_eq!(std::f32::INFINITY.decompose_raw(), (false, 255, 0));
let (sign, expn, signif) = std::f32::NAN.decompose_raw();
assert_eq!((sign, expn), (false, 255));
assert!(signif != 0);
Double precision:
use ieee754::Ieee754;
assert_eq!(1_f64.decompose_raw(), (false, 1023, 0));
assert_eq!(1234.567_f64.decompose_raw(), (false, 1033, 0x34a449ba5e354));
assert_eq!((-0.525_f64).decompose_raw(), (true, 1022, 0xcccc_cccc_cccd));
assert_eq!(std::f64::INFINITY.decompose_raw(), (false, 2047, 0));
let (sign, expn, signif) = std::f64::NAN.decompose_raw();
assert_eq!((sign, expn), (false, 2047));
assert!(signif != 0);
sourcefn recompose_raw(
sign: bool,
expn: Self::RawExponent,
signif: Self::Significand
) -> Self
fn recompose_raw(
sign: bool,
expn: Self::RawExponent,
signif: Self::Significand
) -> Self
Create a Self
out of the three constituent parts of an IEEE754 float.
The exponent should be the raw bits, use exponent_bias
to
compute the offset required, or use recompose
to feed in the
unbiased exponent.
Examples
Single precision:
use ieee754::Ieee754;
assert_eq!(f32::recompose_raw(false, 127, 0), 1.0);
assert_eq!(f32::recompose_raw(false, 137, 0x1a5225), 1234.567);
assert_eq!(f32::recompose_raw(true, 126, 0x66666), -0.525);
assert_eq!(f32::recompose_raw(false, 255, 0), std::f32::INFINITY);
assert!(f32::recompose_raw(false, 255, 1).is_nan());
Double precision:
use ieee754::Ieee754;
assert_eq!(f64::recompose_raw(false, 1023, 0), 1.0);
assert_eq!(f64::recompose_raw(false, 1033, 0x34a449ba5e354), 1234.567);
assert_eq!(f64::recompose_raw(true, 1022, 0xcccc_cccc_cccd), -0.525);
assert_eq!(f64::recompose_raw(false, 2047, 0), std::f64::INFINITY);
assert!(f64::recompose_raw(false, 2047, 1).is_nan());
sourcefn decompose(self) -> (bool, Self::Exponent, Self::Significand)
fn decompose(self) -> (bool, Self::Exponent, Self::Significand)
Break self
into the three constituent parts of an IEEE754 float.
The exponent returned is the true exponent, after accounting for the bias it is stored with. The significand does not include the implicit highest bit (if it exists), e.g. the 24-bit for single precision.
Examples
Single precision:
use ieee754::Ieee754;
assert_eq!(1_f32.decompose(), (false, 0, 0));
assert_eq!(1234.567_f32.decompose(), (false, 10, 0x1a5225));
assert_eq!((-0.525_f32).decompose(), (true, -1, 0x66666));
assert_eq!(std::f32::INFINITY.decompose(), (false, 128, 0));
let (sign, expn, signif) = std::f32::NAN.decompose();
assert_eq!((sign, expn), (false, 128));
assert!(signif != 0);
Double precision:
use ieee754::Ieee754;
assert_eq!(1_f64.decompose(), (false, 0, 0));
assert_eq!(1234.567_f64.decompose(), (false, 10, 0x34a449ba5e354));
assert_eq!((-0.525_f64).decompose(), (true, -1, 0xcccc_cccc_cccd));
assert_eq!(std::f64::INFINITY.decompose(), (false, 1024, 0));
let (sign, expn, signif) = std::f64::NAN.decompose();
assert_eq!((sign, expn), (false, 1024));
assert!(signif != 0);
sourcefn recompose(sign: bool, expn: Self::Exponent, signif: Self::Significand) -> Self
fn recompose(sign: bool, expn: Self::Exponent, signif: Self::Significand) -> Self
Create a Self
out of the three constituent parts of an IEEE754 float.
The exponent should be true exponent, not accounting for any bias. The significand should not include the implicit highest bit (if it exists), e.g. the 24-th bit for signle precision.
Examples
Single precision:
use ieee754::Ieee754;
assert_eq!(f32::recompose(false, 0, 0), 1.0);
assert_eq!(f32::recompose(false, 10, 0x1a5225), 1234.567);
assert_eq!(f32::recompose(true, -1, 0x66666), -0.525);
assert_eq!(f32::recompose(false, 128, 0), std::f32::INFINITY);
assert!(f32::recompose(false, 128, 1).is_nan());
Double precision:
use ieee754::Ieee754;
assert_eq!(f64::recompose(false, 0, 0), 1.0);
assert_eq!(f64::recompose(false, 10, 0x34a449ba5e354), 1234.567);
assert_eq!(f64::recompose(true, -1, 0xcccc_cccc_cccd), -0.525);
assert_eq!(f64::recompose(false, 1024, 0), std::f64::INFINITY);
assert!(f64::recompose(false, 1024, 1).is_nan());
sourcefn total_cmp(&self, other: &Self) -> Ordering
fn total_cmp(&self, other: &Self) -> Ordering
Compare x
and y
using the IEEE-754 totalOrder
predicate
(Section 5.10).
This orders NaNs before or after all non-NaN floats, depending on the sign bit. Using -qNaN to represent a quiet NaN with negative sign bit and similarly for a signalling NaN (sNaN), the order is:
-qNaN < -sNaN < -∞ < -12.34 < -0.0 < +0.0 < +12.34 < +∞ < +sNaN < +qNaN
(NaNs are ordered according to their payload.)
Examples
Single precision:
use std::cmp::Ordering;
use std::f32;
use ieee754::Ieee754;
assert_eq!(0_f32.total_cmp(&0_f32), Ordering::Equal);
assert_eq!(0_f32.total_cmp(&-0_f32), Ordering::Greater);
assert_eq!(0_f32.total_cmp(&1_f32), Ordering::Less);
assert_eq!(1e10_f32.total_cmp(&f32::NEG_INFINITY), Ordering::Greater);
assert_eq!(f32::NAN.total_cmp(&0_f32), Ordering::Greater);
assert_eq!(f32::NAN.total_cmp(&f32::INFINITY), Ordering::Greater);
assert_eq!((-f32::NAN).total_cmp(&f32::NEG_INFINITY), Ordering::Less);
Double precision:
use std::cmp::Ordering;
use std::f64;
use ieee754::Ieee754;
assert_eq!(0_f64.total_cmp(&0_f64), Ordering::Equal);
assert_eq!(0_f64.total_cmp(&-0_f64), Ordering::Greater);
assert_eq!(0_f64.total_cmp(&1_f64), Ordering::Less);
assert_eq!(1e10_f64.total_cmp(&f64::NEG_INFINITY), Ordering::Greater);
assert_eq!(f64::NAN.total_cmp(&0_f64), Ordering::Greater);
assert_eq!(f64::NAN.total_cmp(&f64::INFINITY), Ordering::Greater);
assert_eq!((-f64::NAN).total_cmp(&f64::NEG_INFINITY), Ordering::Less);