Skip to main content

rucc_base/
float.rs

1//! Binary floating point, in software, for every format the compiler has to produce.
2//!
3//! A compiler cannot ask the machine it is running on what a floating constant means. The host
4//! may not have the format at all, `long double` is eighty bits on x86-64 and a hundred and
5//! twenty eight on AArch64 Linux and sixty four on Apple, and `strtod` is the host's libc
6//! rather than the target's semantics. Reproducible output means the same source gives the same
7//! bits whoever compiles it, so the conversion is done here, exactly, in integer arithmetic.
8//!
9//! [`Float`] is a sign, a category, an exponent and a significand of up to a hundred and
10//! thirteen bits, which is every format in [`Format`] including the x87 eighty bit one with its
11//! stored leading bit. The value of a finite number is `significand * 2^(exponent - precision +
12//! 1)`, so the significand is an integer rather than a fraction and the exponent is that of its
13//! leading bit.
14//!
15//! Conversion from text is correctly rounded, round to nearest with ties to even, which is the
16//! only rounding mode a translation-time constant uses. The decimal path scales the number by
17//! powers of two until it is in `[1, 2)` and then reads the significand off it, using the exact
18//! decimal in `decimal.rs` so that no step ever loses a bit. A naive `mantissa * 10^exponent`
19//! in `f64` is wrong in the last place for a noticeable fraction of literals, and the last
20//! place is exactly what a differential test against another compiler notices. Hexadecimal
21//! constants are exact by construction and only have to be rounded once.
22//!
23//! ```
24//! use rucc_base::float::{Float, Format};
25//!
26//! let (value, status) = Float::parse("0.1", Format::Double).expect("a number");
27//! assert_eq!(value.to_bits(), (0.1f64).to_bits() as u128);
28//! assert!(status.has(rucc_base::float::Status::INEXACT));
29//! ```
30//!
31//! The arithmetic is in `arith.rs`, on the same terms: every operation is correctly rounded, to
32//! nearest with ties to even, in integer operations that the host cannot get wrong.
33
34use crate::decimal::{Decimal, Fraction};
35
36mod arith;
37
38/// A binary floating point format.
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
40pub enum Format {
41    /// IEEE binary16, which C spells `_Float16`.
42    Half,
43    /// The brain float, an IEEE binary32 with the low sixteen bits of its significand cut off,
44    /// which C spells `__bf16`. It has the range of a `float` and less than half its precision.
45    BFloat16,
46    /// IEEE binary32, which C spells `float`.
47    Single,
48    /// IEEE binary64, which C spells `double`.
49    Double,
50    /// The x87 eighty bit format, which is `long double` on x86. It is the one format here that
51    /// stores the leading significand bit rather than leaving it implied.
52    X87Extended,
53    /// IEEE binary128, which C spells `_Float128`, and which is `long double` on AArch64 Linux
54    /// and on RISC-V.
55    Quad,
56}
57
58impl Format {
59    /// The short name this format is written under, which is its width in bits for all of them
60    /// but the brain float, whose width does not tell it apart from a `float`.
61    #[must_use]
62    pub const fn name(self) -> &'static str {
63        match self {
64            Format::Half => "f16",
65            Format::BFloat16 => "bf16",
66            Format::Single => "f32",
67            Format::Double => "f64",
68            Format::X87Extended => "f80",
69            Format::Quad => "f128",
70        }
71    }
72
73    /// The format of that name, and [`None`] for a word that is not one.
74    #[must_use]
75    pub fn from_name(name: &str) -> Option<Self> {
76        Some(match name {
77            "f16" => Format::Half,
78            "bf16" => Format::BFloat16,
79            "f32" => Format::Single,
80            "f64" => Format::Double,
81            "f80" => Format::X87Extended,
82            "f128" => Format::Quad,
83            _ => return None,
84        })
85    }
86
87    /// The number of significand bits, counting the leading one whether it is stored or not.
88    #[must_use]
89    pub const fn precision(self) -> u32 {
90        match self {
91            Format::Half => 11,
92            Format::BFloat16 => 8,
93            Format::Single => 24,
94            Format::Double => 53,
95            Format::X87Extended => 64,
96            Format::Quad => 113,
97        }
98    }
99
100    /// The exponent of the largest finite number, which is also the exponent bias.
101    #[must_use]
102    pub const fn max_exponent(self) -> i32 {
103        match self {
104            Format::Half => 15,
105            Format::BFloat16 | Format::Single => 127,
106            Format::Double => 1023,
107            Format::X87Extended | Format::Quad => 16383,
108        }
109    }
110
111    /// The exponent of the smallest normal number.
112    #[must_use]
113    pub const fn min_exponent(self) -> i32 {
114        1 - self.max_exponent()
115    }
116
117    /// The width of the encoding in bits, which for x87 is the eighty bits that matter and not
118    /// the ninety six or hundred and twenty eight an ABI pads them out to.
119    #[must_use]
120    pub const fn width(self) -> u32 {
121        match self {
122            Format::Half | Format::BFloat16 => 16,
123            Format::Single => 32,
124            Format::Double => 64,
125            Format::X87Extended => 80,
126            Format::Quad => 128,
127        }
128    }
129
130    /// Whether the leading significand bit is stored rather than implied.
131    #[must_use]
132    pub const fn has_explicit_integer_bit(self) -> bool {
133        matches!(self, Format::X87Extended)
134    }
135
136    /// The width of the exponent field.
137    const fn exponent_bits(self) -> u32 {
138        self.width() - self.significand_bits() - 1
139    }
140
141    /// The width of the stored significand field.
142    const fn significand_bits(self) -> u32 {
143        if self.has_explicit_integer_bit() { self.precision() } else { self.precision() - 1 }
144    }
145
146    /// A decimal exponent above which every number is too large for the format.
147    ///
148    /// The value is at least `10^(point - 1)`, so a point past this cannot be finite. It is
149    /// deliberately loose: it exists to stop the scaling loop from walking a million powers of
150    /// ten, not to decide anything.
151    const fn max_decimal_exponent(self) -> i32 {
152        (self.max_exponent() + 1) * 30103 / 100000 + 2
153    }
154
155    /// A decimal exponent below which every number rounds to zero.
156    const fn min_decimal_exponent(self) -> i32 {
157        (self.min_exponent() - self.precision() as i32) * 30103 / 100000 - 2
158    }
159}
160
161/// What a conversion had to do to the number to fit it in the format.
162///
163/// A bitmask, so that one conversion can report several. The names are IEEE 754's exceptions,
164/// which is what the diagnostics are ultimately about: GCC warns that a floating constant
165/// exceeds the range of its type, or that it was truncated to zero.
166#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
167pub struct Status(u8);
168
169impl Status {
170    /// The value is exactly what was written.
171    pub const NONE: Status = Status(0);
172    /// The value had to be rounded, so it is not what was written.
173    pub const INEXACT: Status = Status(1);
174    /// The value is too large for the format and became an infinity.
175    pub const OVERFLOW: Status = Status(2);
176    /// The value is too small for the format and became a subnormal or a zero.
177    pub const UNDERFLOW: Status = Status(4);
178    /// The operation has no answer at all, such as an infinity minus an infinity.
179    pub const INVALID: Status = Status(8);
180    /// A number that is not zero was divided by one that is, so the answer is an infinity.
181    pub const DIVIDE_BY_ZERO: Status = Status(16);
182
183    /// Whether every flag in `other` is set here.
184    #[inline]
185    #[must_use]
186    pub const fn has(self, other: Status) -> bool {
187        self.0 & other.0 == other.0
188    }
189
190    /// This set with `other` added.
191    #[inline]
192    #[must_use]
193    pub const fn with(self, other: Status) -> Status {
194        Status(self.0 | other.0)
195    }
196
197    /// Whether nothing happened to the number.
198    #[inline]
199    #[must_use]
200    pub const fn is_none(self) -> bool {
201        self.0 == 0
202    }
203}
204
205/// Why a spelling is not a number.
206///
207/// The caller is expected to have checked the shape of the token already, so these are the
208/// cases a lexer cannot rule out rather than a full grammar.
209#[derive(Debug, Clone, Copy, PartialEq, Eq)]
210pub enum ParseError {
211    /// There is no digit anywhere in it.
212    NoDigits,
213    /// There is an exponent marker with no digits after it.
214    NoExponentDigits,
215    /// There is a character in it that a number does not have.
216    Invalid,
217}
218
219/// What kind of number this is.
220#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
221enum Category {
222    Zero,
223    Finite,
224    Infinite,
225    Nan,
226}
227
228/// A floating point number in a given format.
229///
230/// A finite value is `significand * 2^(exponent - precision + 1)`. A normal number has its
231/// leading significand bit set, a subnormal does not and has the format's minimum exponent.
232#[derive(Debug, Clone, Copy, PartialEq, Eq)]
233pub struct Float {
234    format: Format,
235    category: Category,
236    sign: bool,
237    exponent: i32,
238    significand: u128,
239}
240
241impl Float {
242    /// A zero of the given sign.
243    #[must_use]
244    pub const fn zero(format: Format, sign: bool) -> Float {
245        Float { format, category: Category::Zero, sign, exponent: 0, significand: 0 }
246    }
247
248    /// An infinity of the given sign.
249    #[must_use]
250    pub const fn infinity(format: Format, sign: bool) -> Float {
251        Float { format, category: Category::Infinite, sign, exponent: 0, significand: 0 }
252    }
253
254    /// A nan with a payload, which is the one thing `__builtin_nan` and its family can spell
255    /// that nothing else in C can.
256    ///
257    /// The payload is the low bits of the significand and is cut to the bits there are below the
258    /// quiet bit, which is what gcc does with one that does not fit. A quiet nan is the payload
259    /// with that bit set. A signalling one is the payload without it, and a signalling nan with
260    /// nothing in it is an infinity rather than a nan, so a payload of zero becomes the highest
261    /// bit that is left, which is the value gcc gives `__builtin_nans("")`.
262    #[must_use]
263    pub const fn nan_with(format: Format, sign: bool, quiet: bool, payload: u128) -> Float {
264        let mut significand = payload & (Float::quiet_bit(format) - 1);
265        if quiet {
266            significand |= Float::quiet_bit(format);
267        } else if significand == 0 {
268            significand = Float::quiet_bit(format) >> 1;
269        }
270        Float {
271            format,
272            category: Category::Nan,
273            sign,
274            exponent: 0,
275            significand: significand | Float::leading_bit(format),
276        }
277    }
278
279    /// The bit that tells a quiet nan from a signalling one, which is the highest bit of the
280    /// stored fraction in every format IEEE 754 defines.
281    const fn quiet_bit(format: Format) -> u128 {
282        1u128 << (format.precision() - 2)
283    }
284
285    /// The leading significand bit, in the one format that stores it rather than implying it. It
286    /// is set in every value of that format that is not a zero, a nan and an infinity included.
287    const fn leading_bit(format: Format) -> u128 {
288        if format.has_explicit_integer_bit() { 1u128 << (format.precision() - 1) } else { 0 }
289    }
290
291    /// The format this number is in.
292    #[must_use]
293    pub const fn format(self) -> Format {
294        self.format
295    }
296
297    /// Whether the number is negative, which a zero can be.
298    #[must_use]
299    pub const fn is_negative(self) -> bool {
300        self.sign
301    }
302
303    /// Whether the number is a zero.
304    #[must_use]
305    pub const fn is_zero(self) -> bool {
306        matches!(self.category, Category::Zero)
307    }
308
309    /// Whether the number is an infinity.
310    #[must_use]
311    pub const fn is_infinite(self) -> bool {
312        matches!(self.category, Category::Infinite)
313    }
314
315    /// Whether the number is finite, which a zero is and a nan is not.
316    #[must_use]
317    pub const fn is_finite(self) -> bool {
318        matches!(self.category, Category::Zero | Category::Finite)
319    }
320
321    /// Converts a decimal or hexadecimal spelling into the nearest number in `format`, rounding
322    /// to nearest with ties to even.
323    ///
324    /// The spelling is the number alone: no suffix, because the suffix is what chose the
325    /// format, and no infinity or nan, because C has no spelling for those. A sign is accepted
326    /// even though a C constant never has one, since the value the constant evaluator folds
327    /// does. C23 digit separators are stripped here.
328    ///
329    /// # Errors
330    ///
331    /// [`ParseError`], for a spelling that is not a number at all.
332    pub fn parse(text: &str, format: Format) -> Result<(Float, Status), ParseError> {
333        let bytes = text.as_bytes();
334        let (sign, rest) = match bytes.first() {
335            Some(b'-') => (true, &bytes[1..]),
336            Some(b'+') => (false, &bytes[1..]),
337            _ => (false, bytes),
338        };
339        if rest.len() > 1 && rest[0] == b'0' && rest[1] | 32 == b'x' {
340            hexadecimal(&rest[2..], sign, format)
341        } else {
342            decimal(rest, sign, format)
343        }
344    }
345
346    /// The bits of the encoding, in the low [`Format::width`] bits.
347    ///
348    /// The x87 format keeps its leading significand bit, so its eightieth bit is the sign and
349    /// its sixty fourth is the one every other format leaves implied.
350    #[must_use]
351    pub fn to_bits(self) -> u128 {
352        let format = self.format;
353        let significand_mask = (1u128 << format.significand_bits()) - 1;
354        let (exponent_field, significand_field) = match self.category {
355            Category::Zero => (0, 0),
356            Category::Infinite => (
357                (1u128 << format.exponent_bits()) - 1,
358                if format.has_explicit_integer_bit() {
359                    1u128 << (format.precision() - 1)
360                } else {
361                    0
362                },
363            ),
364            // The significand of a nan is the whole of what it is, since the quiet bit and the
365            // payload are both in it and the exponent is the same for every nan there is.
366            Category::Nan => ((1u128 << format.exponent_bits()) - 1, self.significand),
367            Category::Finite => {
368                let subnormal = self.significand >> (format.precision() - 1) == 0;
369                let field =
370                    if subnormal { 0 } else { (self.exponent + format.max_exponent()) as u128 };
371                (field, self.significand & significand_mask)
372            }
373        };
374        let sign = u128::from(self.sign) << (format.width() - 1);
375        sign | (exponent_field << format.significand_bits()) | significand_field
376    }
377
378    /// Reads a number back out of its encoding, which is what makes [`Float::to_bits`] testable
379    /// and what a constant folded in the IR is stored as.
380    ///
381    /// A nan comes back with the quiet bit and the payload it went in with, so a value that came
382    /// from `__builtin_nan` survives being written down and read back, which is the round trip
383    /// every constant in the IR takes.
384    #[must_use]
385    pub fn from_bits(format: Format, bits: u128) -> Float {
386        let significand_bits = format.significand_bits();
387        let sign = (bits >> (format.width() - 1)) & 1 == 1;
388        let exponent_field =
389            ((bits >> significand_bits) & ((1u128 << format.exponent_bits()) - 1)) as i32;
390        let stored = bits & ((1u128 << significand_bits) - 1);
391        if exponent_field == (1 << format.exponent_bits()) - 1 {
392            // The fraction is what tells an infinity from a nan, and in the x87 format the bit
393            // above the fraction is stored rather than implied and is set in both.
394            let fraction = stored & ((1u128 << (format.precision() - 1)) - 1);
395            if fraction == 0 {
396                return Float::infinity(format, sign);
397            }
398            return Float {
399                format,
400                category: Category::Nan,
401                sign,
402                exponent: 0,
403                significand: stored,
404            };
405        }
406        let implicit = if format.has_explicit_integer_bit() || exponent_field == 0 {
407            0
408        } else {
409            1u128 << (format.precision() - 1)
410        };
411        let significand = stored | implicit;
412        if significand == 0 {
413            return Float::zero(format, sign);
414        }
415        let exponent = if exponent_field == 0 {
416            format.min_exponent()
417        } else {
418            exponent_field - format.max_exponent()
419        };
420        Float { format, category: Category::Finite, sign, exponent, significand }
421    }
422
423    /// A hexadecimal spelling that [`Float::parse`] turns back into exactly this number.
424    ///
425    /// Hexadecimal rather than decimal, because a hexadecimal constant is exact by construction
426    /// and a decimal one is not: printing a number in decimal so that it reads back unchanged
427    /// needs a shortest-round-trip algorithm, and printing it in decimal without one silently
428    /// changes the program. A printer that changes a constant is worse than a printer whose
429    /// output is unfamiliar, so this is `0x1p+0` where a reader would rather see `1.0`.
430    ///
431    /// The significand is written as an integer and the exponent scales it, so the spelling is
432    /// `significand * 2^exponent` with no leading digit to argue about. Trailing zero digits are
433    /// taken off, which is what makes a round number short.
434    ///
435    /// An infinity has no spelling in C at all. What comes back for one is an exponent past the
436    /// top of the format, which converts back to an infinity with the overflow that a constant
437    /// only ever became an infinity by. A nan is spelled `nan` and does not read back, since
438    /// there is no exponent that gives one and no constant that is one.
439    #[must_use]
440    pub fn to_hex(self) -> String {
441        let sign = if self.sign { "-" } else { "" };
442        match self.category {
443            Category::Nan => format!("{sign}nan"),
444            Category::Infinite => format!("{sign}0x1p+{}", self.format.max_exponent() + 1),
445            Category::Zero => format!("{sign}0x0p+0"),
446            Category::Finite => {
447                let mut significand = self.significand;
448                let mut exponent = self.exponent - (self.format.precision() as i32 - 1);
449                while significand & 0xf == 0 {
450                    significand >>= 4;
451                    exponent += 4;
452                }
453                format!("{sign}0x{significand:x}p{exponent:+}")
454            }
455        }
456    }
457}
458
459/// Converts a decimal spelling.
460fn decimal(bytes: &[u8], sign: bool, format: Format) -> Result<(Float, Status), ParseError> {
461    let mut digits = Vec::new();
462    let mut integer_digits = 0i32;
463    let mut seen_point = false;
464    let mut seen_digit = false;
465    let mut index = 0;
466    while index < bytes.len() {
467        match bytes[index] {
468            byte @ b'0'..=b'9' => {
469                digits.push(byte - b'0');
470                if !seen_point {
471                    integer_digits += 1;
472                }
473                seen_digit = true;
474            }
475            b'\'' => {}
476            b'.' if !seen_point => seen_point = true,
477            b'e' | b'E' => break,
478            _ => return Err(ParseError::Invalid),
479        }
480        index += 1;
481    }
482    if !seen_digit {
483        return Err(ParseError::NoDigits);
484    }
485    let mut point = integer_digits;
486    if index < bytes.len() {
487        point = point.saturating_add(exponent_of(&bytes[index + 1..])?);
488    }
489    Ok(convert(Decimal::new(digits, point), sign, format))
490}
491
492/// Converts a hexadecimal spelling, which is exact until the one rounding at the end.
493fn hexadecimal(bytes: &[u8], sign: bool, format: Format) -> Result<(Float, Status), ParseError> {
494    let mut significand: u128 = 0;
495    let mut exponent = 0i32;
496    let mut sticky = false;
497    let mut seen_point = false;
498    let mut seen_digit = false;
499    let mut index = 0;
500    while index < bytes.len() {
501        let byte = bytes[index];
502        let digit = match byte {
503            b'0'..=b'9' => byte - b'0',
504            b'a'..=b'f' => byte - b'a' + 10,
505            b'A'..=b'F' => byte - b'A' + 10,
506            b'\'' => {
507                index += 1;
508                continue;
509            }
510            b'.' if !seen_point => {
511                seen_point = true;
512                index += 1;
513                continue;
514            }
515            b'p' | b'P' => break,
516            _ => return Err(ParseError::Invalid),
517        };
518        seen_digit = true;
519        if significand.leading_zeros() >= 4 {
520            significand = (significand << 4) | u128::from(digit);
521            if seen_point {
522                exponent -= 4;
523            }
524        } else {
525            // Past a hundred and twenty eight bits the digits cannot change the value, only
526            // whether it is exactly halfway, which is what the sticky bit is for.
527            sticky |= digit != 0;
528            if !seen_point {
529                exponent += 4;
530            }
531        }
532        index += 1;
533    }
534    if !seen_digit {
535        return Err(ParseError::NoDigits);
536    }
537    if index < bytes.len() {
538        exponent = exponent.saturating_add(exponent_of(&bytes[index + 1..])?);
539    }
540    Ok(round(significand, exponent, sticky, sign, format))
541}
542
543/// Reads the digits of an exponent, which may be signed.
544fn exponent_of(bytes: &[u8]) -> Result<i32, ParseError> {
545    let (negative, digits) = match bytes.first() {
546        Some(b'-') => (true, &bytes[1..]),
547        Some(b'+') => (false, &bytes[1..]),
548        _ => (false, bytes),
549    };
550    if digits.is_empty() {
551        return Err(ParseError::NoExponentDigits);
552    }
553    let mut value = 0i32;
554    for &byte in digits {
555        if byte == b'\'' {
556            continue;
557        }
558        if !byte.is_ascii_digit() {
559            return Err(ParseError::Invalid);
560        }
561        // An exponent far past the format's range is the same as one at the edge of it, so it
562        // saturates rather than overflowing.
563        value = value.saturating_mul(10).saturating_add(i32::from(byte - b'0'));
564    }
565    Ok(if negative { -value } else { value })
566}
567
568/// Scales an exact decimal down to the format's significand and rounds it.
569fn convert(mut value: Decimal, sign: bool, format: Format) -> (Float, Status) {
570    if value.is_zero() {
571        return (Float::zero(format, sign), Status::NONE);
572    }
573    if value.point() > format.max_decimal_exponent() {
574        return (Float::infinity(format, sign), Status::OVERFLOW.with(Status::INEXACT));
575    }
576    if value.point() < format.min_decimal_exponent() {
577        return (Float::zero(format, sign), Status::UNDERFLOW.with(Status::INEXACT));
578    }
579
580    // Scale until the value is in `[1, 2)`, counting the powers of two taken out of it. Each
581    // step is an underestimate of the distance left, so no step overshoots and the loop always
582    // moves, which is what stops it oscillating.
583    let mut exponent = 0i32;
584    loop {
585        let point = value.point();
586        if point > 1 || (point == 1 && value.first_digit() >= 2) {
587            let step = binary_digits(point - 1).clamp(1, 60);
588            value.shift(-step);
589            exponent += step;
590        } else if point < 1 {
591            let step = (1 + binary_digits(-point)).clamp(1, 60);
592            value.shift(step);
593            exponent -= step;
594        } else {
595            break;
596        }
597    }
598
599    // The significand is the value scaled by this many powers of two, clamped so that a number
600    // below the smallest normal loses precision instead of exponent.
601    let precision = format.precision() as i32;
602    let scale = (exponent - precision + 1).max(format.min_exponent() - precision + 1);
603    value.shift(exponent - scale);
604    let (integer, fraction) = value.round_to_u128();
605    let rounded = match fraction {
606        Fraction::Zero | Fraction::BelowHalf => integer,
607        Fraction::Half => integer + (integer & 1),
608        Fraction::AboveHalf => integer + 1,
609    };
610    finish(rounded, scale, fraction != Fraction::Zero, sign, format)
611}
612
613/// Roughly how many binary digits a decimal one of this many digits has, never overestimating.
614const fn binary_digits(decimal: i32) -> i32 {
615    decimal * 33219 / 10000
616}
617
618/// Rounds `significand * 2^exponent` into the format, with `sticky` saying that something
619/// nonzero was already dropped below it.
620fn round(
621    significand: u128,
622    exponent: i32,
623    sticky: bool,
624    sign: bool,
625    format: Format,
626) -> (Float, Status) {
627    if significand == 0 {
628        return (Float::zero(format, sign), Status::NONE);
629    }
630    let precision = format.precision() as i32;
631    let leading = (128 - significand.leading_zeros()) as i32;
632    let scale = (exponent + leading - precision).max(format.min_exponent() - precision + 1);
633    let mut sticky = sticky;
634    let (integer, half) = if scale <= exponent {
635        (significand << (exponent - scale), false)
636    } else {
637        let drop = (scale - exponent) as u32;
638        if drop >= 128 {
639            sticky = true;
640            (0, false)
641        } else {
642            let half = (significand >> (drop - 1)) & 1 == 1;
643            sticky |= drop > 1 && significand & ((1u128 << (drop - 1)) - 1) != 0;
644            (significand >> drop, half)
645        }
646    };
647    let rounded = if half && (sticky || integer & 1 == 1) { integer + 1 } else { integer };
648    finish(rounded, scale, half || sticky, sign, format)
649}
650
651/// Turns a rounded significand and the power of two it is scaled by into a number, handling the
652/// carry out of the significand and the two ends of the format's range.
653fn finish(
654    significand: u128,
655    scale: i32,
656    inexact: bool,
657    sign: bool,
658    format: Format,
659) -> (Float, Status) {
660    let precision = format.precision();
661    let mut significand = significand;
662    let mut scale = scale;
663    if significand >> precision != 0 {
664        // Rounding up carried out of the top bit, which only ever gives a power of two.
665        significand >>= 1;
666        scale += 1;
667    }
668    let mut status = if inexact { Status::INEXACT } else { Status::NONE };
669    if significand == 0 {
670        return (Float::zero(format, sign), status.with(Status::UNDERFLOW));
671    }
672    let exponent = scale + precision as i32 - 1;
673    if exponent > format.max_exponent() {
674        return (
675            Float::infinity(format, sign),
676            status.with(Status::OVERFLOW).with(Status::INEXACT),
677        );
678    }
679    let normal = significand >> (precision - 1) != 0;
680    if !normal && inexact {
681        status = status.with(Status::UNDERFLOW);
682    }
683    let exponent = if normal { exponent } else { format.min_exponent() };
684    (Float { format, category: Category::Finite, sign, exponent, significand }, status)
685}
686
687#[cfg(test)]
688mod tests {
689    use super::*;
690
691    /// The bits a `double` conversion gives, next to what Rust's own parser gives.
692    fn double(text: &str) -> u128 {
693        Float::parse(text, Format::Double).expect("a number").0.to_bits()
694    }
695
696    /// The bits a `float` conversion gives.
697    fn single(text: &str) -> u128 {
698        Float::parse(text, Format::Single).expect("a number").0.to_bits()
699    }
700
701    #[test]
702    fn the_ordinary_numbers_land_where_the_host_would_put_them() {
703        for text in ["0", "1", "2", "0.5", "1.5", "3.14159", "2.718281828459045", "100", "1e10"] {
704            let host = text.parse::<f64>().expect("a number Rust reads too");
705            assert_eq!(double(text), u128::from(host.to_bits()), "{text}");
706        }
707    }
708
709    #[test]
710    fn a_number_that_needs_the_last_bit_rounded_gets_it_right() {
711        // Every one of these is a literal a naive `mantissa * 10^exponent` gets wrong, and the
712        // last is the longest one a `double` conversion has to read to round correctly.
713        let hard = [
714            "0.1",
715            "0.3",
716            "2.2250738585072011e-308",
717            "2.2250738585072014e-308",
718            "1.7976931348623157e308",
719            "4.9406564584124654e-324",
720            "5e-324",
721            "8.98846567431158e307",
722            "9007199254740993",
723            "123456789012345678901234567890",
724            "1.000000000000000000000000000000000000000000000000000000000000000001",
725            "7.8459735791271921e65",
726            "3.518437208883201171875e13",
727            "0.500000000000000166533453693773481063544750213623046875",
728        ];
729        for text in hard {
730            let host = text.parse::<f64>().expect("a number Rust reads too");
731            assert_eq!(double(text), u128::from(host.to_bits()), "{text}");
732        }
733    }
734
735    #[test]
736    fn the_number_that_takes_seven_hundred_and_sixty_seven_digits() {
737        // The exact decimal of a `double` halfway case. A conversion that truncates its input
738        // rounds this one the wrong way, which is the bug this buffer size exists to avoid.
739        let text = concat!(
740            "2.47032822920623272088284396434110686182529901307162382",
741            "35378852574870103599108683372845652890455735483022221802",
742            "58573249056416711547735232764105795166208503595426876755",
743            "62317084535693494535245273750735013572761315046354601316",
744            "12127849863326369238975694273040488011871029093711789936",
745            "42245692702737764465109076580131048946378905599180391359",
746            "70011386455512221706120629864144453927884519445934871524",
747            "63344875888932891414823975864211858166195965106373837732",
748            "34435703331457550505022232309998195892058070506176382679",
749            "16323484472119097902806154870514036458498974142754747141",
750            "39683784321102080606305920253373777969877864922227306716",
751            "01324339457879181214233820577228206278891620001855078759",
752            "16278352090142077553206262229158550205643778244387017277",
753            "94459649305087139089301871550805125768938177360937844105",
754            "63661045147381814281647890691181239104545396303476425117",
755            "7562185422741845851144691421326303120484712594187004993e-324"
756        );
757        let host = text.parse::<f64>().expect("a number Rust reads too");
758        assert_eq!(double(text), u128::from(host.to_bits()));
759    }
760
761    #[test]
762    fn a_sweep_of_random_numbers_agrees_with_rust_in_every_bit() {
763        // A conversion that is wrong in the last place is wrong on a small fraction of inputs,
764        // so this is a sweep rather than a handful. The generator is a fixed sequence, so a
765        // failure names the same number on every machine.
766        let mut state = 0x2545_f491_4f6c_dd1du64;
767        for _ in 0..4000 {
768            state = state.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
769            let digits = state >> 11;
770            let exponent = (state % 600) as i32 - 300;
771            let text = format!("{digits}e{exponent}");
772            let host = text.parse::<f64>().expect("a number Rust reads too");
773            assert_eq!(double(&text), u128::from(host.to_bits()), "{text}");
774            let host = text.parse::<f32>().expect("a number Rust reads too");
775            assert_eq!(single(&text), u128::from(host.to_bits()), "{text} as a float");
776        }
777    }
778
779    #[test]
780    fn the_ends_of_the_range_are_an_infinity_and_a_zero() {
781        let (value, status) = Float::parse("1e400", Format::Double).expect("a number");
782        assert!(value.is_infinite() && status.has(Status::OVERFLOW));
783        let (value, status) = Float::parse("1e-400", Format::Double).expect("a number");
784        assert!(value.is_zero() && status.has(Status::UNDERFLOW) && status.has(Status::INEXACT));
785        // The largest `double` is finite and the next number up is not.
786        let (value, status) = Float::parse("1.7976931348623157e308", Format::Double).expect("one");
787        assert!(value.is_finite() && !status.has(Status::OVERFLOW));
788        let (value, _) = Float::parse("1.8e308", Format::Double).expect("a number");
789        assert!(value.is_infinite());
790        // Half the smallest subnormal rounds to zero, and just over half rounds up to it.
791        assert_eq!(double("2.4e-324"), u128::from((0f64).to_bits()));
792        assert_eq!(double("2.5e-324"), 1);
793    }
794
795    #[test]
796    fn a_number_that_is_exactly_what_was_written_says_so() {
797        assert!(Float::parse("1", Format::Double).expect("a number").1.is_none());
798        assert!(Float::parse("0.5", Format::Double).expect("a number").1.is_none());
799        assert!(Float::parse("0.1", Format::Double).expect("a number").1.has(Status::INEXACT));
800        // A number small enough to lose bits is inexact and underflowed, both.
801        let (_, status) = Float::parse("1e-320", Format::Double).expect("a number");
802        assert!(status.has(Status::INEXACT) && status.has(Status::UNDERFLOW));
803    }
804
805    #[test]
806    fn a_hexadecimal_constant_is_exact_and_needs_no_scaling() {
807        assert_eq!(double("0x1p0"), u128::from((1f64).to_bits()));
808        assert_eq!(double("0x1.8p1"), u128::from((3f64).to_bits()));
809        assert_eq!(double("0x1p-1074"), 1);
810        assert_eq!(double("0xa.bp-4"), u128::from((0.66796875f64).to_bits()));
811        assert_eq!(double("0X1.FFFFFFFFFFFFFP+1023"), u128::from(f64::MAX.to_bits()));
812        assert!(Float::parse("0x1p0", Format::Double).expect("a number").1.is_none());
813        // Seventeen hexadecimal digits is more than a `double` has, so this one rounds.
814        let (_, status) = Float::parse("0x1.00000000000008p0", Format::Double).expect("a number");
815        assert!(status.has(Status::INEXACT));
816        assert_eq!(double("0x1.00000000000008p0"), u128::from((1f64).to_bits()));
817        assert_eq!(double("0x1.00000000000018p0"), u128::from((1f64).to_bits() + 2));
818    }
819
820    #[test]
821    fn digit_separators_are_not_part_of_the_number() {
822        assert_eq!(double("1'000.000'1"), double("1000.0001"));
823        assert_eq!(double("0x1'0p0"), double("16.0"));
824        assert_eq!(double("1e1'0"), double("1e10"));
825    }
826
827    #[test]
828    fn a_spelling_that_is_not_a_number_says_which_way_it_is_wrong() {
829        assert_eq!(Float::parse("", Format::Double), Err(ParseError::NoDigits));
830        assert_eq!(Float::parse(".", Format::Double), Err(ParseError::NoDigits));
831        assert_eq!(Float::parse("1e", Format::Double), Err(ParseError::NoExponentDigits));
832        assert_eq!(Float::parse("1e+", Format::Double), Err(ParseError::NoExponentDigits));
833        assert_eq!(Float::parse("0x1p", Format::Double), Err(ParseError::NoExponentDigits));
834        assert_eq!(Float::parse("0xp1", Format::Double), Err(ParseError::NoDigits));
835        assert_eq!(Float::parse("1x0", Format::Double), Err(ParseError::Invalid));
836    }
837
838    #[test]
839    fn a_sign_is_accepted_although_a_c_constant_never_has_one() {
840        let (value, _) = Float::parse("-1.5", Format::Double).expect("a number");
841        assert!(value.is_negative());
842        assert_eq!(value.to_bits(), u128::from((-1.5f64).to_bits()));
843        let (value, _) = Float::parse("-0.0", Format::Double).expect("a number");
844        assert!(value.is_zero() && value.is_negative());
845        assert_eq!(value.to_bits(), u128::from((-0.0f64).to_bits()));
846    }
847
848    #[test]
849    fn every_format_says_how_wide_its_fields_are() {
850        for format in [
851            Format::Half,
852            Format::BFloat16,
853            Format::Single,
854            Format::Double,
855            Format::X87Extended,
856            Format::Quad,
857        ] {
858            assert_eq!(
859                format.exponent_bits() + format.significand_bits() + 1,
860                format.width(),
861                "{format:?}"
862            );
863            assert_eq!(format.min_exponent(), 1 - format.max_exponent());
864        }
865        assert_eq!(Format::Half.exponent_bits(), 5);
866        assert_eq!(Format::BFloat16.exponent_bits(), 8);
867        assert_eq!(Format::Single.exponent_bits(), 8);
868        assert_eq!(Format::Double.exponent_bits(), 11);
869        assert_eq!(Format::X87Extended.exponent_bits(), 15);
870        assert_eq!(Format::Quad.exponent_bits(), 15);
871    }
872
873    #[test]
874    fn a_number_survives_a_trip_through_its_encoding() {
875        for format in [
876            Format::Half,
877            Format::BFloat16,
878            Format::Single,
879            Format::Double,
880            Format::X87Extended,
881            Format::Quad,
882        ] {
883            for text in ["0", "-0", "1", "-1.5", "3.14159", "1e-5", "65504", "0x1p-20"] {
884                let (value, _) = Float::parse(text, format).expect("a number");
885                let bits = value.to_bits();
886                assert_eq!(Float::from_bits(format, bits).to_bits(), bits, "{text} in {format:?}");
887            }
888            assert_eq!(
889                Float::from_bits(format, Float::infinity(format, false).to_bits()).to_bits(),
890                Float::infinity(format, false).to_bits()
891            );
892        }
893    }
894
895    #[test]
896    fn a_hexadecimal_spelling_reads_back_as_the_number_it_came_from() {
897        for format in [
898            Format::Half,
899            Format::BFloat16,
900            Format::Single,
901            Format::Double,
902            Format::X87Extended,
903            Format::Quad,
904        ] {
905            for text in [
906                "0", "-0", "1", "-1", "0.5", "-1.5", "3.14159", "1e-5", "0x1p-20", "0.1", "255",
907                "1e30",
908            ] {
909                let (value, _) = Float::parse(text, format).expect("a number");
910                let spelling = value.to_hex();
911                let (again, status) = Float::parse(&spelling, format).expect("a number");
912                assert_eq!(again.to_bits(), value.to_bits(), "{text} as {spelling} in {format:?}");
913                // Exact, except where the number was already an infinity, which reading the
914                // spelling back has to overflow into rather than land on.
915                let rounded = status.has(Status::INEXACT) || status.has(Status::OVERFLOW);
916                assert_eq!(rounded, !value.is_finite(), "{spelling} in {format:?}");
917            }
918            // A subnormal, which has leading zeros where a normal number has its implied one.
919            let tiny = Float::from_bits(format, 1);
920            let (again, _) = Float::parse(&tiny.to_hex(), format).expect("a number");
921            assert_eq!(again.to_bits(), tiny.to_bits(), "the smallest subnormal in {format:?}");
922            // An infinity, which C cannot spell and which comes back by overflowing again.
923            let huge = Float::infinity(format, true);
924            let (again, status) = Float::parse(&huge.to_hex(), format).expect("a number");
925            assert!(again.is_infinite() && again.is_negative(), "{format:?}");
926            assert!(status.has(Status::OVERFLOW));
927        }
928    }
929
930    #[test]
931    fn a_round_number_gets_a_short_spelling() {
932        let hex = |text: &str| Float::parse(text, Format::Double).expect("a number").0.to_hex();
933        assert_eq!(hex("1"), "0x1p+0");
934        assert_eq!(hex("-1"), "-0x1p+0");
935        assert_eq!(hex("0"), "0x0p+0");
936        assert_eq!(hex("-0"), "-0x0p+0");
937        assert_eq!(hex("2"), "0x1p+1");
938        assert_eq!(hex("0.5"), "0x1p-1");
939        assert_eq!(hex("0.1"), "0x1999999999999ap-56");
940    }
941
942    #[test]
943    fn the_narrow_formats_round_where_they_are_supposed_to() {
944        // `_Float16` has eleven bits, so its largest finite number is 65504 and the next power
945        // of two is an infinity. `__bf16` has eight, so it loses a `float`'s low bits and keeps
946        // its range, which is the whole point of the format.
947        let (value, status) = Float::parse("65504", Format::Half).expect("a number");
948        assert!(value.is_finite() && status.is_none());
949        assert_eq!(value.to_bits(), 0x7bff);
950        let (value, _) = Float::parse("65536", Format::Half).expect("a number");
951        assert!(value.is_infinite());
952        assert_eq!(Float::parse("1", Format::Half).expect("one").0.to_bits(), 0x3c00);
953        assert_eq!(Float::parse("1", Format::BFloat16).expect("one").0.to_bits(), 0x3f80);
954        assert_eq!(Float::parse("1e30", Format::BFloat16).expect("big").0.to_bits(), 0x714a);
955        // The smallest `_Float16` subnormal, and half of it.
956        assert_eq!(Float::parse("0x1p-24", Format::Half).expect("tiny").0.to_bits(), 1);
957        assert!(Float::parse("0x1p-26", Format::Half).expect("tinier").0.is_zero());
958    }
959
960    #[test]
961    fn the_x87_format_stores_the_bit_the_others_leave_implied() {
962        // 1.0 is 0x3fff8000000000000000: the exponent field, then a significand whose top bit
963        // is stored rather than implied. Every other format here would have zeros there.
964        let one = Float::parse("1", Format::X87Extended).expect("one").0;
965        assert_eq!(one.to_bits(), 0x3fff_8000_0000_0000_0000);
966        assert_eq!(
967            Float::parse("2", Format::X87Extended).expect("two").0.to_bits(),
968            0x4000_8000_0000_0000_0000
969        );
970        // Sixty four bits of precision, so this is exact where a `double` would round it.
971        let (value, status) = Float::parse("9007199254740993", Format::X87Extended).expect("one");
972        assert!(status.is_none());
973        assert_eq!(value.to_bits(), 0x4034_8000_0000_0000_0400);
974        // Measured, by compiling the constant with gcc 13.3 on x86-64 and reading the ten
975        // bytes back out of the program rather than trusting a table.
976        assert_eq!(
977            Float::parse("0.1", Format::X87Extended).expect("a tenth").0.to_bits(),
978            0x3ffb_cccc_cccc_cccc_cccd
979        );
980        // A subnormal four thousand powers of ten down, which is three of the smallest number
981        // the format has. gcc puts the same three there.
982        assert_eq!(Float::parse("1e-4950", Format::X87Extended).expect("tiny").0.to_bits(), 3);
983    }
984
985    #[test]
986    fn the_quad_format_has_a_hundred_and_thirteen_bits_of_it() {
987        assert_eq!(
988            Float::parse("1", Format::Quad).expect("one").0.to_bits(),
989            0x3fff_0000_0000_0000_0000_0000_0000_0000
990        );
991        // 0.1 in binary128, which is the same digits a `double` gets and then sixty more bits.
992        assert_eq!(
993            Float::parse("0.1", Format::Quad).expect("a tenth").0.to_bits(),
994            0x3ffb_9999_9999_9999_9999_9999_9999_999a
995        );
996        // Also measured against gcc, through `__float128`.
997        assert_eq!(
998            Float::parse("3.14159", Format::Quad).expect("pi, roughly").0.to_bits(),
999            0x4000_921f_9f01_b866_e43a_a79b_badc_0981
1000        );
1001        let (value, status) = Float::parse("1e5000", Format::Quad).expect("a number");
1002        assert!(value.is_infinite() && status.has(Status::OVERFLOW));
1003        let (value, _) = Float::parse("1e-5000", Format::Quad).expect("a number");
1004        assert!(value.is_zero());
1005    }
1006
1007    /// Every number here is what gcc 16 puts in the object for the `__builtin_nan` that spells
1008    /// it, read back out of the object rather than reasoned about.
1009    #[test]
1010    fn a_nan_with_a_payload_has_the_bits_gcc_gives_it() {
1011        let double = |quiet, payload| Float::nan_with(Format::Double, false, quiet, payload);
1012        assert_eq!(double(true, 0).to_bits(), 0x7ff8_0000_0000_0000, "__builtin_nan(\"\")");
1013        assert_eq!(double(true, 1).to_bits(), 0x7ff8_0000_0000_0001, "__builtin_nan(\"0x1\")");
1014        assert_eq!(double(true, 8).to_bits(), 0x7ff8_0000_0000_0008, "__builtin_nan(\"010\")");
1015        // A signalling nan with nothing in it would be an infinity, so the highest bit below the
1016        // quiet one goes in instead.
1017        assert_eq!(double(false, 0).to_bits(), 0x7ff4_0000_0000_0000, "__builtin_nans(\"\")");
1018        assert_eq!(double(false, 1).to_bits(), 0x7ff0_0000_0000_0001, "__builtin_nans(\"0x1\")");
1019        // A payload that fills the fraction, and one bit more than fits, which is cut.
1020        assert_eq!(double(true, 0xf_ffff_ffff_ffff).to_bits(), 0x7fff_ffff_ffff_ffff);
1021        assert_eq!(double(true, 1 << 52).to_bits(), 0x7ff8_0000_0000_0000);
1022        assert_eq!(
1023            Float::nan_with(Format::Single, false, true, 1).to_bits(),
1024            0x7fc0_0001,
1025            "__builtin_nanf(\"0x1\")"
1026        );
1027        assert_eq!(
1028            Float::nan_with(Format::Single, false, false, 0).to_bits(),
1029            0x7fa0_0000,
1030            "__builtin_nansf(\"\")"
1031        );
1032        // The x87 format stores the leading significand bit, which is set in a nan as in
1033        // everything else that is not a zero.
1034        assert_eq!(
1035            Float::nan_with(Format::X87Extended, false, true, 1).to_bits(),
1036            0x7fff_c000_0000_0000_0001,
1037            "__builtin_nanl(\"0x1\") on x86"
1038        );
1039        assert_eq!(
1040            Float::nan_with(Format::X87Extended, false, false, 0).to_bits(),
1041            0x7fff_a000_0000_0000_0000,
1042            "__builtin_nansl(\"\") on x86"
1043        );
1044    }
1045
1046    /// A payload is part of the value, so it has to survive being written down and read back.
1047    #[test]
1048    fn a_payload_comes_back_out_of_the_encoding_it_went_into() {
1049        for format in [Format::Half, Format::Single, Format::Double, Format::X87Extended] {
1050            for (quiet, payload) in [(true, 0), (true, 1), (false, 3), (true, 5)] {
1051                let nan = Float::nan_with(format, false, quiet, payload);
1052                assert!(nan.is_nan(), "{format:?}");
1053                assert_eq!(Float::from_bits(format, nan.to_bits()), nan, "{format:?} {payload}");
1054            }
1055            // The sign of a nan is its own, and negating one leaves the payload alone.
1056            let nan = Float::nan_with(format, true, true, 7);
1057            assert!(nan.is_negative() && nan.negated().negated() == nan, "{format:?}");
1058        }
1059    }
1060}