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