Trait ieee754::Ieee754 [−][src]
Types that are IEEE754 floating point numbers.
Associated Types
type Bits: Bits
[src]
A type that represents the raw bits of Self
.
type Exponent
[src]
A type large enough to store the true exponent of Self
.
type RawExponent
[src]
A type large enough to store the raw exponent (i.e. with the bias).
type Significand
[src]
A type large enough to store the significand of Self
.
Required methods
fn upto(self, lim: Self) -> Iter<Self>ⓘ
[src]
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);
fn next(self) -> Self
[src]
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);
fn prev(self) -> Self
[src]
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);
fn ulp(self) -> Option<Self>
[src]
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.
Examples
Single precision:
use std::f32; use ieee754::Ieee754; assert_eq!(0_f32.ulp(), Some(1.4e-45)); assert_eq!(1_f32.ulp(), Some(1.1920928955078125e-07)); assert_eq!((-1_f32).ulp(), Some(1.1920928955078125e-07)); // 2^23 assert_eq!(8_388_608_f32.ulp(), Some(1.0)); // 2^24 - 1, the largest f32 with ULP 1 assert_eq!(16_777_215_f32.ulp(), Some(1.0)); // 2^24 assert_eq!(16_777_216_f32.ulp(), Some(2.0)); // non-finite assert_eq!(f32::INFINITY.ulp(), None); assert_eq!(f32::NAN.ulp(), None);
Double precision:
use std::f64; use ieee754::Ieee754; assert_eq!(0_f64.ulp(), Some(4.9e-324)); assert_eq!(1_f64.ulp(), Some(2.220446049250313e-16)); assert_eq!((-1_f64).ulp(), Some(2.220446049250313e-16)); // 2^52 assert_eq!(4_503_599_627_370_496_f64.ulp(), Some(1.0)); // 2^53 - 1, the largest f64 with ULP 1 assert_eq!(9_007_199_254_740_991_f64.ulp(), Some(1.0)); // 2^53 assert_eq!(9_007_199_254_740_992_f64.ulp(), Some(2.0)); // non-finite assert_eq!(f64::INFINITY.ulp(), None); assert_eq!(f64::NAN.ulp(), None);
fn bits(self) -> Self::Bits
[src]
View self
as a collection of bits.
Examples
use ieee754::Ieee754; let x: f32 = 1.0; assert_eq!(x.bits(), 0x3f80_0000);
fn from_bits(x: Self::Bits) -> Self
[src]
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);
fn exponent_bias() -> Self::Exponent
[src]
Get the bias of the stored exponent.
Examples
use ieee754::Ieee754; assert_eq!(f32::exponent_bias(), 127); assert_eq!(f64::exponent_bias(), 1023);
fn decompose_raw(self) -> (bool, Self::RawExponent, Self::Significand)
[src]
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);
fn recompose_raw(
sign: bool,
expn: Self::RawExponent,
signif: Self::Significand
) -> Self
[src]
sign: bool,
expn: Self::RawExponent,
signif: Self::Significand
) -> Self
Create a Self
out of the three constituent parts of an IEEE754 float.
This returns (-1)sign
×
1.signif
× 2expn
- bias, where
sign
is treated as iftrue
==1
(meaningtrue
is negative),- 1.
signif
refers to placing the bits ofsignif
as the fractional part of a number between 1 and 2, and - bias is the exponent bias for this float (see [
exponent_bias
]).
The exponent should be the raw bits: use exponent_bias
to
compute the offset required, or use recompose
to feed in an
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());
fn decompose(self) -> (bool, Self::Exponent, Self::Significand)
[src]
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);
fn recompose(
sign: bool,
expn: Self::Exponent,
signif: Self::Significand
) -> Self
[src]
sign: bool,
expn: Self::Exponent,
signif: Self::Significand
) -> Self
Create a Self
out of the three constituent parts of an IEEE754 float.
This returns (-1)sign
×
1.signif
× 2expn
, where
sign
is treated as iftrue
==1
(meaningtrue
is negative), and- 1.
signif
refers to placing the bits ofsignif
as the fractional part of a number between 1 and 2.
The exponent should be the 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 single precision.
Examples
Single precision:
use ieee754::Ieee754; // normal numbers 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); // infinity assert_eq!(f32::recompose(false, 128, 0), std::f32::INFINITY); // NaN assert!(f32::recompose(false, 128, 1).is_nan());
Double precision:
use ieee754::Ieee754; // normal numbers 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); // infinity assert_eq!(f64::recompose(false, 1024, 0), std::f64::INFINITY); // NaN assert!(f64::recompose(false, 1024, 1).is_nan());
fn total_cmp(&self, other: &Self) -> Ordering
[src]
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
Sorting:
use std::f32; use ieee754::Ieee754; let mut data = vec![0.0, f32::NEG_INFINITY, -1.0, f32::INFINITY, f32::NAN, -0.0, 12.34e5, -f32::NAN]; data.sort_by(|a, b| a.total_cmp(b)); assert_eq!(format!("{:.0?}", data), "[NaN, -inf, -1, -0, 0, 1234000, inf, NaN]");
Single precision:
use std::cmp::Ordering; use std::f32; use ieee754::Ieee754; // normal comparison assert_eq!(0_f32.total_cmp(&0_f32), Ordering::Equal); assert_eq!(0_f32.total_cmp(&1_f32), Ordering::Less); assert_eq!(1e10_f32.total_cmp(&f32::NEG_INFINITY), Ordering::Greater); // signed zero assert_eq!(0_f32.total_cmp(&-0_f32), Ordering::Greater); // NaNs 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; // normal comparison assert_eq!(0_f64.total_cmp(&0_f64), Ordering::Equal); assert_eq!(0_f64.total_cmp(&1_f64), Ordering::Less); assert_eq!(1e10_f64.total_cmp(&f64::NEG_INFINITY), Ordering::Greater); // signed zero assert_eq!(0_f64.total_cmp(&-0_f64), Ordering::Greater); // NaNs 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);
fn abs(self) -> Self
[src]
Return the absolute value of x
.
This provides a no_std/core-only version of the built-in abs
in
std
, until
#50145 is
addressed.
Examples
Single precision:
#![no_std] use core::f32; use ieee754::Ieee754; assert_eq!((0_f32).abs(), 0.0); assert_eq!((12.34_f32).abs(), 12.34); assert_eq!((-12.34_f32).abs(), 12.34); assert_eq!(f32::INFINITY.abs(), f32::INFINITY); assert_eq!(f32::NEG_INFINITY.abs(), f32::INFINITY); assert!(f32::NAN.abs().is_nan());
Double precision:
#![no_std] use core::f64; use ieee754::Ieee754; assert_eq!((0_f64).abs(), 0.0); assert_eq!((12.34_f64).abs(), 12.34); assert_eq!((-12.34_f64).abs(), 12.34); assert_eq!(f64::INFINITY.abs(), f64::INFINITY); assert_eq!(f64::NEG_INFINITY.abs(), f64::INFINITY); assert!(f64::NAN.abs().is_nan());
fn copy_sign(self, sign: Self) -> Self
[src]
Return a float with the magnitude of self
but the sign of
sign
.
If sign
is NaN, this still uses its sign bit, and does not
(necessarily) return NaN.
Examples
Single precision:
use std::f32; use ieee754::Ieee754; // normal numbers assert_eq!(1_f32.copy_sign(1.0), 1.0); assert_eq!(2_f32.copy_sign(-1.0), -2.0); assert_eq!((-3_f32).copy_sign(1.0), 3.0); assert_eq!((-4_f32).copy_sign(-1.0), -4.0); // infinities assert_eq!(5_f32.copy_sign(f32::NEG_INFINITY), -5.0); assert_eq!(f32::NEG_INFINITY.copy_sign(1.0), f32::INFINITY); // signs of zeros matter assert_eq!((-6_f32).copy_sign(0.0), 6.0); assert_eq!(7_f32.copy_sign(-0.0), -7.0); // NaNs only propagate on the self argument assert!(f32::NAN.copy_sign(1.0).is_nan()); assert_eq!(8_f32.copy_sign(-f32::NAN), -8.0);
Double precision:
use std::f64; use ieee754::Ieee754; // normal numbers assert_eq!(1_f64.copy_sign(1.0), 1.0); assert_eq!(2_f64.copy_sign(-1.0), -2.0); assert_eq!((-3_f64).copy_sign(1.0), 3.0); assert_eq!((-4_f64).copy_sign(-1.0), -4.0); // infinities assert_eq!(5_f64.copy_sign(f64::NEG_INFINITY), -5.0); assert_eq!(f64::NEG_INFINITY.copy_sign(1.0), f64::INFINITY); // signs of zeros matter assert_eq!((-6_f64).copy_sign(0.0), 6.0); assert_eq!(7_f64.copy_sign(-0.0), -7.0); // NaNs only propagate on the self argument assert!(f64::NAN.copy_sign(1.0).is_nan()); assert_eq!(8_f64.copy_sign(-f64::NAN), -8.0);
fn sign(self) -> Self
[src]
Return the sign of x
.
This provides a no_std/core-only function similar to the
built-in signum
in std
(until
#50145 is
addressed). This sign
function differs at two values; it
matches the mathematical definitions when self == 0.0
:
x | x.signum() (std ) | x.sign() (ieee754 ) |
---|---|---|
< 0.0 | −1.0 | −1.0 |
−0.0 | −1.0 | −0.0 |
+0.0 | +1.0 | +0.0 |
> 0.0 | +1.0 | +1.0 |
NaN | NaN | NaN |
Examples
Single precision:
use std::f32; use std::cmp::Ordering; use ieee754::Ieee754; // zeros assert_eq!(0_f32.sign().total_cmp(&0.0), Ordering::Equal); assert_eq!((-0_f32).sign().total_cmp(&-0.0), Ordering::Equal); // normal numbers assert_eq!((12.34_f32).sign(), 1.0); assert_eq!((-12.34_f32).sign(), -1.0); // extremes assert_eq!(f32::INFINITY.sign(), 1.0); assert_eq!(f32::NEG_INFINITY.sign(), -1.0); assert!(f32::NAN.sign().is_nan());
Double precision:
use std::f64; use std::cmp::Ordering; use ieee754::Ieee754; // zeros assert_eq!(0_f64.sign().total_cmp(&0.0), Ordering::Equal); assert_eq!((-0_f64).sign().total_cmp(&-0.0), Ordering::Equal); // normal numbers assert_eq!((12.34_f64).sign(), 1.0); assert_eq!((-12.34_f64).sign(), -1.0); // extremes assert_eq!(f64::INFINITY.sign(), 1.0); assert_eq!(f64::NEG_INFINITY.sign(), -1.0); assert!(f64::NAN.sign().is_nan());
fn rel_error(self, exact: Self) -> Self
[src]
Compute the (generalized) signed relative error of self
as an approximation to exact
.
This computes the signed value: positive indicates self
in
the opposite direction to 0 from exact
; negative indicates
self
is in the same direction as 0 from exact
. Use
x.rel_error(exact).abs()
to get the non-signed relative
error.
The “generalized” refers to exact
being 0 or ±∞ the handling
of which is designed to indicate a “failure” (infinite error),
if self
doesn’t precisely equal exact
. This behaviour is
designed for checking output of algorithms on floats when it
is often desirable to match 0.0 and ±∞ perfectly.
The values of this function are:
exact | x | x.rel_error(exact) |
---|---|---|
NaN | any value | NaN |
any value | NaN | NaN |
0 | equal to exact | 0 |
0 | not equal to exact | signum(x ) × ∞ |
±∞ | equal to exact | 0 |
±∞ | not equal to exact | -∞ |
any other value | any value | (x - exact) / exact |
The sign of a zero-valued argument has no effect on the result of this function.
Examples
Single precision:
use std::f32; use ieee754::Ieee754; assert_eq!(4_f32.rel_error(4.0), 0.0); assert_eq!(3_f32.rel_error(4.0), -0.25); assert_eq!(5_f32.rel_error(4.0), 0.25); // zero assert_eq!(0_f32.rel_error(0.0), 0.0); assert_eq!(1_f32.rel_error(0.0), f32::INFINITY); assert_eq!((-1_f32).rel_error(0.0), f32::NEG_INFINITY); // infinities assert_eq!(f32::INFINITY.rel_error(f32::INFINITY), 0.0); assert_eq!(0_f32.rel_error(f32::INFINITY), f32::NEG_INFINITY); assert_eq!(f32::NEG_INFINITY.rel_error(f32::NEG_INFINITY), 0.0); assert_eq!(0_f32.rel_error(f32::NEG_INFINITY), f32::NEG_INFINITY); // NaNs assert!(f32::NAN.rel_error(4.0).is_nan()); assert!(4_f32.rel_error(f32::NAN).is_nan());
Double precision:
use std::f64; use ieee754::Ieee754; assert_eq!(4_f64.rel_error(4.0), 0.0); assert_eq!(3_f64.rel_error(4.0), -0.25); assert_eq!(5_f64.rel_error(4.0), 0.25); // zero assert_eq!(0_f64.rel_error(0.0), 0.0); assert_eq!(1_f64.rel_error(0.0), f64::INFINITY); assert_eq!((-1_f64).rel_error(0.0), f64::NEG_INFINITY); // infinities assert_eq!(f64::INFINITY.rel_error(f64::INFINITY), 0.0); assert_eq!(0_f64.rel_error(f64::INFINITY), f64::NEG_INFINITY); assert_eq!(f64::NEG_INFINITY.rel_error(f64::NEG_INFINITY), 0.0); assert_eq!(0_f64.rel_error(f64::NEG_INFINITY), f64::NEG_INFINITY); // NaNs assert!(f64::NAN.rel_error(4.0).is_nan()); assert!(4_f64.rel_error(f64::NAN).is_nan());
Implementors
impl Ieee754 for f32
[src]
type Bits = u32
type Exponent = i16
type RawExponent = u8
type Significand = u32
fn upto(self, lim: Self) -> Iter<Self>ⓘ
[src]
fn ulp(self) -> Option<Self>
[src]
fn next(self) -> Self
[src]
fn prev(self) -> Self
[src]
fn exponent_bias() -> Self::Exponent
[src]
fn bits(self) -> Self::Bits
[src]
fn from_bits(bits: Self::Bits) -> Self
[src]
fn decompose_raw(self) -> (bool, Self::RawExponent, Self::Significand)
[src]
fn recompose_raw(
sign: bool,
expn: Self::RawExponent,
signif: Self::Significand
) -> Self
[src]
sign: bool,
expn: Self::RawExponent,
signif: Self::Significand
) -> Self
fn decompose(self) -> (bool, Self::Exponent, Self::Significand)
[src]
fn recompose(
sign: bool,
expn: Self::Exponent,
signif: Self::Significand
) -> Self
[src]
sign: bool,
expn: Self::Exponent,
signif: Self::Significand
) -> Self
fn total_cmp(&self, other: &Self) -> Ordering
[src]
fn abs(self) -> Self
[src]
fn copy_sign(self, sign: Self) -> Self
[src]
fn sign(self) -> Self
[src]
fn rel_error(self, exact: Self) -> Self
[src]
impl Ieee754 for f64
[src]
type Bits = u64
type Exponent = i16
type RawExponent = u16
type Significand = u64
fn upto(self, lim: Self) -> Iter<Self>ⓘ
[src]
fn ulp(self) -> Option<Self>
[src]
fn next(self) -> Self
[src]
fn prev(self) -> Self
[src]
fn exponent_bias() -> Self::Exponent
[src]
fn bits(self) -> Self::Bits
[src]
fn from_bits(bits: Self::Bits) -> Self
[src]
fn decompose_raw(self) -> (bool, Self::RawExponent, Self::Significand)
[src]
fn recompose_raw(
sign: bool,
expn: Self::RawExponent,
signif: Self::Significand
) -> Self
[src]
sign: bool,
expn: Self::RawExponent,
signif: Self::Significand
) -> Self
fn decompose(self) -> (bool, Self::Exponent, Self::Significand)
[src]
fn recompose(
sign: bool,
expn: Self::Exponent,
signif: Self::Significand
) -> Self
[src]
sign: bool,
expn: Self::Exponent,
signif: Self::Significand
) -> Self