Skip to main content

Float128

Struct Float128 

Source
pub struct Float128 { /* private fields */ }
Expand description

An IEEE 754-2008 binary128 value.

Held as the 128-bit pattern, because that is what goes on the wire and every operation here is defined on it. to_be_bytes and from_be_bytes are the wire form: CORBA Figure 9.2 shows the whole sixteen bytes reversed between the two orders, not two eight-byte halves swapped independently, and RTI Connext 7.7 was measured doing exactly that (docs/float128-column.md §2).

§Equality

PartialEq is IEEE equality, the same as f64: -0.0 == 0.0, and a NaN equals nothing including itself. So there is no Eq, no Ord and no Hash — a key holder wants the bit pattern, which Float128::to_bits and Float128::to_be_bytes give, and a total order is Float128::total_cmp. Deriving Eq on IEEE equality would make -0.0 and 0.0 interchangeable in a hash map, which is how a key holder loses an instance.

Implementations§

Source§

impl Float128

Source

pub fn total_cmp(self, other: Self) -> Ordering

IEEE 754-2008 clause 5.10 totalOrder.

A total order over every bit pattern: -NaN < -inf < … < -0.0 < +0.0 < … < +inf < +NaN, with NaNs ordered by payload. This is what a @key member and a sorted expectation need — partial_cmp returning None for a NaN key would leave the sort order to whatever the caller’s comparator does with None, which is how two peers disagree about instance order for a sample neither considers unusual.

The same construction f64::total_cmp uses: read the pattern as a sign-magnitude integer and map it onto a two’s-complement one.

Source

pub fn total_max(self, other: Self) -> Self

The larger of two values under Self::total_cmp.

Source

pub fn total_min(self, other: Self) -> Self

The smaller of two values under Self::total_cmp.

Source§

impl Float128

Source

pub fn from_f64(value: f64) -> Self

From an f64. Always exact: binary128 covers every binary64 value, subnormals included, with 60 fraction bits to spare.

Examples found in repository?
examples/emit_oracle_input.rs (line 47)
34fn main() {
35    let named = [
36        Float128::ZERO,
37        Float128::NEG_ZERO,
38        Float128::ONE,
39        Float128::NEG_ONE,
40        Float128::MAX,
41        Float128::MIN,
42        Float128::MIN_POSITIVE,
43        Float128::MIN_SUBNORMAL,
44        Float128::EPSILON,
45        Float128::from_bits(Float128::ONE.to_bits() + 1),
46        Float128::from_bits(Float128::MIN_POSITIVE.to_bits() - 1),
47        Float128::from_f64(1.5),
48        Float128::from_f64(-2.75),
49        Float128::from_f64(0.1),
50        Float128::from_f64(f64::MAX),
51        Float128::from_f64(f64::MIN_POSITIVE),
52        Float128::from_bits(Float128::ONE.to_bits() | (1u128 << 52)),
53        Float128::from_bits(Float128::ONE.to_bits() | (1u128 << 12)),
54    ];
55    let mut rng = Xorshift(0x0aac_1e50_dead_beef);
56    let mut patterns: Vec<Float128> = named.to_vec();
57    for _ in 0..500 {
58        let bits = (u128::from(rng.next_u64()) << 64) | u128::from(rng.next_u64());
59        // Finite only: quadmath prints `inf` and `nan` without digits,
60        // and those cases are pinned by name in the unit tests instead.
61        let exponent = u128::from(rng.next_u64() as u16 % 0x7fff) << 112;
62        patterns.push(Float128::from_bits(
63            (bits & !(0x7fffu128 << 112)) | exponent,
64        ));
65    }
66    for value in patterns {
67        println!("{:032x} {}", value.to_bits(), value.to_shortest_decimal());
68    }
69}
Source

pub fn from_f32(value: f32) -> Self

From an f32. Always exact, for the same reason.

Source

pub fn from_i128_rounded(value: i128) -> Self

From any signed integer up to 128 bits, rounding to nearest with ties to even. Exact for everything up to 2^113.

Source

pub fn from_u128_rounded(value: u128) -> Self

From any unsigned integer up to 128 bits, rounding to nearest with ties to even. Exact for everything up to 2^113.

Source

pub fn try_from_i128(value: i128) -> Result<Self, Inexact<Self>>

From a signed integer, refusing one that does not fit exactly.

§Errors

Inexact when the integer needs more than 113 significant bits, carrying what it rounds to.

Source

pub fn try_from_u128(value: u128) -> Result<Self, Inexact<Self>>

From an unsigned integer, refusing one that does not fit exactly.

§Errors

Inexact when the integer needs more than 113 significant bits, carrying what it rounds to.

Source§

impl Float128

Source

pub fn to_f64_rounded(self) -> f64

To an f64, rounding to nearest with ties to even.

Overflow gives an infinity and underflow a signed zero, which is what IEEE 754-2008 clause 7.4 requires; both are inexact and Self::to_f64 reports them.

Source

pub fn to_f64(self) -> Result<f64, Inexact<f64>>

To an f64 when the value fits one exactly.

§Errors

Inexact carrying the rounded result. This is the refusal the long double column needed: the old writer took an f64 and put it on the wire as sixteen bytes, so a value with 113 significant bits was narrowed on the way in and nobody was told.

Source

pub fn to_f32_rounded(self) -> f32

To an f32, rounding to nearest with ties to even.

Source

pub fn to_f32(self) -> Result<f32, Inexact<f32>>

To an f32 when the value fits one exactly.

§Errors

Inexact carrying the rounded result.

Source§

impl Float128

Source

pub fn to_i128(self) -> Result<i128, Inexact<i128>>

The value truncated toward zero, when it is an exact integer that fits an i128.

§Errors

Inexact carrying the truncated result, for a value with a fractional part, an infinity, a NaN, or a magnitude past the destination.

Source

pub fn to_i64(self) -> Result<i64, Inexact<i64>>

As Self::to_i128, into an i64.

§Errors

Inexact carrying the saturated or truncated result.

Source§

impl Float128

Source

pub const fn quiet_nan(payload: u128) -> Self

A quiet NaN carrying payload in its low fraction bits.

A wire test needs a NaN it can recognise on the other side, and Float128::NAN is one pattern out of 2^113. The payload is masked to the bits below the quiet flag, so no argument can produce an infinity by accident.

Source

pub const fn neg_quiet_nan(payload: u128) -> Self

The same, negative.

Source§

impl Float128

Source

pub fn to_exact_decimal(&self) -> String

Every digit the value has, exactly.

1.5 gives "1.5"; the smallest subnormal gives its full 11 500 digits. Infinities and NaNs give "inf", "-inf" and "nan", which is what FromStr reads back.

Source

pub fn to_shortest_decimal(&self) -> String

The fewest digits that read back as this exact bit pattern.

Found by rounding the exact expansion to one digit, then two, and asking FromStr whether it comes back — so the answer is true of this parser rather than true of a rule about digit counts. Thirty-six always succeeds; Float128::DIGITS_ROUND_TRIP is that bound.

Examples found in repository?
examples/emit_oracle_input.rs (line 67)
34fn main() {
35    let named = [
36        Float128::ZERO,
37        Float128::NEG_ZERO,
38        Float128::ONE,
39        Float128::NEG_ONE,
40        Float128::MAX,
41        Float128::MIN,
42        Float128::MIN_POSITIVE,
43        Float128::MIN_SUBNORMAL,
44        Float128::EPSILON,
45        Float128::from_bits(Float128::ONE.to_bits() + 1),
46        Float128::from_bits(Float128::MIN_POSITIVE.to_bits() - 1),
47        Float128::from_f64(1.5),
48        Float128::from_f64(-2.75),
49        Float128::from_f64(0.1),
50        Float128::from_f64(f64::MAX),
51        Float128::from_f64(f64::MIN_POSITIVE),
52        Float128::from_bits(Float128::ONE.to_bits() | (1u128 << 52)),
53        Float128::from_bits(Float128::ONE.to_bits() | (1u128 << 12)),
54    ];
55    let mut rng = Xorshift(0x0aac_1e50_dead_beef);
56    let mut patterns: Vec<Float128> = named.to_vec();
57    for _ in 0..500 {
58        let bits = (u128::from(rng.next_u64()) << 64) | u128::from(rng.next_u64());
59        // Finite only: quadmath prints `inf` and `nan` without digits,
60        // and those cases are pinned by name in the unit tests instead.
61        let exponent = u128::from(rng.next_u64() as u16 % 0x7fff) << 112;
62        patterns.push(Float128::from_bits(
63            (bits & !(0x7fffu128 << 112)) | exponent,
64        ));
65    }
66    for value in patterns {
67        println!("{:032x} {}", value.to_bits(), value.to_shortest_decimal());
68    }
69}
Source§

impl Float128

Source

pub const ZERO: Self

Positive zero.

Source

pub const NEG_ZERO: Self

Negative zero. Distinct from Self::ZERO on the wire, equal to it under ==, ordered below it by Self::total_cmp.

Source

pub const ONE: Self

One.

Source

pub const NEG_ONE: Self

Minus one.

Source

pub const INFINITY: Self

Positive infinity.

Source

pub const NEG_INFINITY: Self

Negative infinity.

Source

pub const NAN: Self

A quiet NaN with no payload.

Source

pub const MAX: Self

The largest finite value, (2 - 2^-112) * 2^16383.

Source

pub const MIN: Self

The most negative finite value.

Source

pub const MIN_POSITIVE: Self

The smallest positive normal value, 2^-16382.

Source

pub const MIN_SUBNORMAL: Self

The smallest positive value of any kind, 2^-16494.

Source

pub const EPSILON: Self

The step from 1.0 to the next larger value, 2^-112.

Source

pub const MANTISSA_DIGITS: u32 = SIGNIFICAND_BITS

Significand bits including the implicit leading one: 113.

Source

pub const DIGITS_ROUND_TRIP: usize = 36

Decimal digits that always round-trip: ceil(113 * log10 2) + 1.

Thirty-six is the number Float128::to_shortest_decimal never exceeds and the number a peer needs to read one back exactly.

Source

pub const fn from_bits(bits: u128) -> Self

From the raw 128-bit pattern.

Examples found in repository?
examples/emit_oracle_input.rs (line 45)
34fn main() {
35    let named = [
36        Float128::ZERO,
37        Float128::NEG_ZERO,
38        Float128::ONE,
39        Float128::NEG_ONE,
40        Float128::MAX,
41        Float128::MIN,
42        Float128::MIN_POSITIVE,
43        Float128::MIN_SUBNORMAL,
44        Float128::EPSILON,
45        Float128::from_bits(Float128::ONE.to_bits() + 1),
46        Float128::from_bits(Float128::MIN_POSITIVE.to_bits() - 1),
47        Float128::from_f64(1.5),
48        Float128::from_f64(-2.75),
49        Float128::from_f64(0.1),
50        Float128::from_f64(f64::MAX),
51        Float128::from_f64(f64::MIN_POSITIVE),
52        Float128::from_bits(Float128::ONE.to_bits() | (1u128 << 52)),
53        Float128::from_bits(Float128::ONE.to_bits() | (1u128 << 12)),
54    ];
55    let mut rng = Xorshift(0x0aac_1e50_dead_beef);
56    let mut patterns: Vec<Float128> = named.to_vec();
57    for _ in 0..500 {
58        let bits = (u128::from(rng.next_u64()) << 64) | u128::from(rng.next_u64());
59        // Finite only: quadmath prints `inf` and `nan` without digits,
60        // and those cases are pinned by name in the unit tests instead.
61        let exponent = u128::from(rng.next_u64() as u16 % 0x7fff) << 112;
62        patterns.push(Float128::from_bits(
63            (bits & !(0x7fffu128 << 112)) | exponent,
64        ));
65    }
66    for value in patterns {
67        println!("{:032x} {}", value.to_bits(), value.to_shortest_decimal());
68    }
69}
Source

pub const fn to_bits(self) -> u128

The raw 128-bit pattern.

Examples found in repository?
examples/emit_oracle_input.rs (line 45)
34fn main() {
35    let named = [
36        Float128::ZERO,
37        Float128::NEG_ZERO,
38        Float128::ONE,
39        Float128::NEG_ONE,
40        Float128::MAX,
41        Float128::MIN,
42        Float128::MIN_POSITIVE,
43        Float128::MIN_SUBNORMAL,
44        Float128::EPSILON,
45        Float128::from_bits(Float128::ONE.to_bits() + 1),
46        Float128::from_bits(Float128::MIN_POSITIVE.to_bits() - 1),
47        Float128::from_f64(1.5),
48        Float128::from_f64(-2.75),
49        Float128::from_f64(0.1),
50        Float128::from_f64(f64::MAX),
51        Float128::from_f64(f64::MIN_POSITIVE),
52        Float128::from_bits(Float128::ONE.to_bits() | (1u128 << 52)),
53        Float128::from_bits(Float128::ONE.to_bits() | (1u128 << 12)),
54    ];
55    let mut rng = Xorshift(0x0aac_1e50_dead_beef);
56    let mut patterns: Vec<Float128> = named.to_vec();
57    for _ in 0..500 {
58        let bits = (u128::from(rng.next_u64()) << 64) | u128::from(rng.next_u64());
59        // Finite only: quadmath prints `inf` and `nan` without digits,
60        // and those cases are pinned by name in the unit tests instead.
61        let exponent = u128::from(rng.next_u64() as u16 % 0x7fff) << 112;
62        patterns.push(Float128::from_bits(
63            (bits & !(0x7fffu128 << 112)) | exponent,
64        ));
65    }
66    for value in patterns {
67        println!("{:032x} {}", value.to_bits(), value.to_shortest_decimal());
68    }
69}
Source

pub const fn from_be_bytes(bytes: [u8; 16]) -> Self

From sixteen big-endian bytes — the CDR big-endian wire form.

Source

pub const fn to_be_bytes(self) -> [u8; 16]

Sixteen big-endian bytes.

Source

pub const fn from_le_bytes(bytes: [u8; 16]) -> Self

From sixteen little-endian bytes — the CDR little-endian wire form, which is the big-endian one reversed as a whole.

Source

pub const fn to_le_bytes(self) -> [u8; 16]

Sixteen little-endian bytes.

Source

pub const fn is_sign_negative(self) -> bool

The sign bit, as it is stored. True for negative, including -0.0 and a negative NaN.

Source

pub const fn is_sign_positive(self) -> bool

The complement of Self::is_sign_negative.

Source

pub const fn classify(self) -> Class

What kind of value this is.

Source

pub const fn is_nan(self) -> bool

Whether this is a NaN.

Source

pub const fn is_infinite(self) -> bool

Whether this is an infinity.

Source

pub const fn is_finite(self) -> bool

Whether this is neither infinite nor a NaN.

Source

pub const fn is_zero(self) -> bool

Whether this is +0.0 or -0.0.

Source

pub const fn is_subnormal(self) -> bool

Whether this is finite, non-zero and below Self::MIN_POSITIVE.

Source

pub const fn is_normal(self) -> bool

Whether this is finite and normal — not zero, not subnormal.

Source

pub const fn is_quiet_nan(self) -> bool

Whether this NaN is quiet. False for anything that is not a NaN.

Source

pub const fn abs(self) -> Self

The same magnitude with the sign bit cleared. NaN payloads and signalling-ness survive, per IEEE 754-2008 clause 5.5.1.

Source

pub const fn neg(self) -> Self

The same magnitude with the sign bit flipped.

Source

pub const fn copysign(self, sign: Self) -> Self

This magnitude with sign’s sign bit.

Source

pub const fn decompose(self) -> Option<(bool, u128, i32)>

The value as (negative, significand, exponent) with value = (-1)^negative * significand * 2^exponent.

None for an infinity or a NaN, which no such triple describes. The significand is the integral one — the implicit leading bit is materialised for a normal value — so the triple is exact and needs no separate “is subnormal” flag to interpret.

Source§

impl Float128

Source

pub fn from_x87_extended(value: Extended80) -> Self

From x87 double-extended. Always exact: 64 significand bits fit inside 113, and the two formats share an exponent bias and range.

The unnormal and pseudo-* encodings the 8087 defined and the 80387 dropped — a cleared integer bit with a non-zero exponent — have no binary128 counterpart. They are decoded as what the significand and exponent say, which is what every current x86 treats them as when it does not fault.

Source

pub fn from_x87_padded_bytes(bytes: [u8; 16]) -> Self

From the sixteen bytes an x86-64 Fast DDS or OpenDDS writes.

The padding is dropped; see Extended80::from_padded_le_bytes.

Source

pub fn to_x87_extended(self) -> (Extended80, bool)

To x87 double-extended, rounding to nearest with ties to even.

Returns the value and whether the conversion was exact. It is inexact whenever the significand needs more than 64 bits, which is most of binary128 — that is the whole cost of the x86 dialect, and it is returned rather than swallowed so a bridge can refuse.

Source

pub fn to_x87_padded_bytes(self) -> ([u8; 16], bool)

To the sixteen bytes an x86-64 long double occupies, padding zeroed.

The boolean is Float128::to_x87_extended’s: true when the value survived.

Trait Implementations§

Source§

impl Clone for Float128

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Float128

Source§

impl Debug for Float128

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Float128

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Display for Float128

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

The shortest round-tripping decimal.

Source§

impl From<f32> for Float128

Source§

fn from(value: f32) -> Self

Converts to this type from the input type.
Source§

impl From<f64> for Float128

Source§

fn from(value: f64) -> Self

Converts to this type from the input type.
Source§

impl FromStr for Float128

Source§

fn from_str(text: &str) -> Result<Self, Self::Err>

Correctly rounded, round to nearest with ties to even.

Never goes through an f64: a two-step parse rounds twice, and double rounding gets the last bit wrong for the values that matter here.

Source§

type Err = ParseFloat128Error

The associated error which can be returned from parsing.
Source§

impl Neg for Float128

Source§

type Output = Float128

The resulting type after applying the - operator.
Source§

fn neg(self) -> Self

Performs the unary - operation. Read more
Source§

impl PartialEq for Float128

Source§

fn eq(&self, other: &Self) -> bool

IEEE 754-2008 clause 5.11 compareQuietEqual.

-0.0 == 0.0, and a NaN is equal to nothing, itself included. The same contract f64 has, so a generated structure holding a Float128 compares the way the same structure holding a double does — a binding whose equality changed with the member’s width would be a binding that fails a round trip test for a reason that has nothing to do with the wire.

1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl PartialOrd for Float128

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

IEEE 754-2008 clause 5.11. None when either side is a NaN, the unordered case.

1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl TryFrom<Float128> for f64

Source§

type Error = Inexact<f64>

The type returned in the event of a conversion error.
Source§

fn try_from(value: Float128) -> Result<Self, Self::Error>

Performs the conversion.
Source§

impl TryFrom<Float128> for f32

Source§

type Error = Inexact<f32>

The type returned in the event of a conversion error.
Source§

fn try_from(value: Float128) -> Result<Self, Self::Error>

Performs the conversion.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.