Skip to main content

Module float

Module float 

Source
Expand description

Binary floating point, in software, for every format the compiler has to produce.

A compiler cannot ask the machine it is running on what a floating constant means. The host may not have the format at all, long double is eighty bits on x86-64 and a hundred and twenty eight on AArch64 Linux and sixty four on Apple, and strtod is the host’s libc rather than the target’s semantics. Reproducible output means the same source gives the same bits whoever compiles it, so the conversion is done here, exactly, in integer arithmetic.

Float is a sign, a category, an exponent and a significand of up to a hundred and thirteen bits, which is every format in Format including the x87 eighty bit one with its stored leading bit. The value of a finite number is significand * 2^(exponent - precision + 1), so the significand is an integer rather than a fraction and the exponent is that of its leading bit.

Conversion from text is correctly rounded, round to nearest with ties to even, which is the only rounding mode a translation-time constant uses. The decimal path scales the number by powers of two until it is in [1, 2) and then reads the significand off it, using the exact decimal in decimal.rs so that no step ever loses a bit. A naive mantissa * 10^exponent in f64 is wrong in the last place for a noticeable fraction of literals, and the last place is exactly what a differential test against another compiler notices. Hexadecimal constants are exact by construction and only have to be rounded once.

use rucc_base::float::{Float, Format};

let (value, status) = Float::parse("0.1", Format::Double).expect("a number");
assert_eq!(value.to_bits(), (0.1f64).to_bits() as u128);
assert!(status.has(rucc_base::float::Status::INEXACT));

Arithmetic is not here yet. The constant evaluator needs it and will bring it.

Structs§

Float
A floating point number in a given format.
Status
What a conversion had to do to the number to fit it in the format.

Enums§

Format
A binary floating point format.
ParseError
Why a spelling is not a number.