Skip to main content

rucc_base/float/
arith.rs

1//! Arithmetic on [`Float`], correctly rounded, in integer operations only.
2//!
3//! The constant evaluator folds `1.0 / 3.0` at translation time and the program it compiles
4//! computes the same thing at run time, and the two have to agree in the last bit. Asking the
5//! host to do the arithmetic gets that wrong in three separate ways: the host may not have the
6//! format at all, its `long double` is not the target's, and a compiler that folds one way on one
7//! machine and another way on another is a compiler whose output depends on where it ran.
8//!
9//! So the operations are here, on integers, rounded to nearest with ties to even. Each one
10//! computes the exact answer to more bits than the format has and rounds once, which is what
11//! makes it correctly rounded: the answer is the representable number nearest the exact result.
12//! Every operation below either fits that exact result in a [`u128`] or keeps a sticky bit saying
13//! that something nonzero was dropped below the bits it kept, which is all the rounding needs to
14//! know about what it cannot see.
15//!
16//! # Naming
17//!
18//! An operation returns a number and a [`Status`], because the caller has to be able to warn that
19//! a constant overflowed or that a fold was inexact, so these cannot be the `std::ops` traits and
20//! are named for what they return rather than for what they do. [`Float`] deliberately implements
21//! no arithmetic trait at all: an operator with a discarded status is exactly the kind of quiet
22//! wrongness this module exists to prevent.
23//!
24//! The three operations that return a number alone are the ones that cannot round.
25//! [`Float::to_integral`] lands on a number the format already holds, and [`Float::larger`] and
26//! [`Float::smaller`] hand back an operand rather than computing anything, so a [`Status`] from any
27//! of them would be a value the caller has to look at and that is always nothing.
28//!
29//! # What is not here
30//!
31//! A rounding mode other than to nearest, for the operations that round. C's `#pragma STDC
32//! FENV_ACCESS` and the dynamic rounding modes change what the running program does rather than
33//! what a translation time constant means, and a constant is folded to nearest whatever the mode
34//! is. [`Float::to_integral`] takes a direction because there the direction is the operation: what
35//! `ceil` and `floor` differ in is where they land and not what mode they ran under.
36//!
37//! A nan payload out of an operation. [`Float`] carries one, since `__builtin_nan` can spell one
38//! and a static initializer written with it has to keep it, but every nan produced here is the
39//! default quiet one. Propagating a payload would mean deciding which of two operands wins, which
40//! IEEE 754 leaves to the implementation and which no C program can see.
41
42use std::cmp::Ordering;
43
44/// Which integer a value is taken to, for [`Float::to_integral`].
45///
46/// The four are C's `trunc`, `ceil`, `floor` and `round`, and they are the four of that family
47/// whose answer does not depend on the rounding mode the program is running under. `rint` and
48/// `nearbyint` are the two that do, and there is no variant for them here: a compiler that folded
49/// one would be answering for a mode it cannot know, which is why gcc will not fold one either and
50/// says so by refusing `static double x = __builtin_rint(2.5);` as not a constant.
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub enum Integral {
53    /// Toward zero, which drops the fraction and keeps the sign. C's `trunc`.
54    TowardZero,
55    /// Toward positive infinity. C's `ceil`.
56    Upward,
57    /// Toward negative infinity. C's `floor`.
58    Downward,
59    /// To the nearest, with a half going away from zero rather than to even. C's `round`, and the
60    /// one place in C where a tie does not go to even.
61    NearestTiesAway,
62}
63
64use crate::float::{Category, Float, Format, Status, round};
65
66/// How many bits are kept below the significand while two numbers are lined up for an addition.
67///
68/// Two of them are the guard and round bits an addition needs in order to round correctly, and
69/// the third is where the sticky bit lands, so anything shifted past all three is nonzero or it
70/// is nothing, which is the one fact the rounding needs about it.
71const GUARD: u32 = 3;
72
73impl Float {
74    /// A quiet nan, which is what an operation with no answer gives.
75    ///
76    /// The default one, whose payload is nothing. [`Float::nan_with`] is where a payload comes
77    /// from, and there is only one thing in C that can spell one.
78    #[must_use]
79    pub const fn nan(format: Format) -> Float {
80        Float {
81            format,
82            category: Category::Nan,
83            sign: false,
84            exponent: 0,
85            significand: Float::quiet_bit(format) | Float::leading_bit(format),
86        }
87    }
88
89    /// Whether the number is a nan.
90    #[must_use]
91    pub const fn is_nan(self) -> bool {
92        matches!(self.category, Category::Nan)
93    }
94
95    /// The number with its sign flipped, which is exact and which a zero and a nan both have.
96    #[must_use]
97    pub const fn negated(self) -> Float {
98        Float { sign: !self.sign, ..self }
99    }
100
101    /// The number without its sign, which is exact.
102    #[must_use]
103    pub const fn abs(self) -> Float {
104        Float { sign: false, ..self }
105    }
106
107    /// The number with the sign given, which is exact and which is what `copysign` answers. Every
108    /// value has a sign to be set, a zero and a nan as much as a number.
109    #[must_use]
110    pub const fn with_sign(self, sign: bool) -> Float {
111        Float { sign, ..self }
112    }
113
114    /// `self + other`, rounded to nearest with ties to even.
115    ///
116    /// A nan operand gives a nan and nothing else. Two infinities of opposite sign give a nan and
117    /// [`Status::INVALID`], because the answer depends on how they got there. Two zeros give a
118    /// negative zero only when both of them are negative, which is the round to nearest rule and
119    /// the reason `x + 0.0` is not a way to drop a sign.
120    ///
121    /// # Panics
122    ///
123    /// If the two numbers are not in the same format. The usual arithmetic conversions have
124    /// already made them so, and converting here would be a conversion nobody asked for.
125    #[must_use]
126    pub fn sum(self, other: Float) -> (Float, Status) {
127        self.total(other, false)
128    }
129
130    /// `self - other`, rounded to nearest with ties to even.
131    ///
132    /// This is the sum of `self` and the negation of `other`, which is exactly what it is in IEEE
133    /// 754, so a subtraction that cancels completely gives a positive zero and an infinity minus
134    /// itself gives a nan.
135    ///
136    /// # Panics
137    ///
138    /// If the two numbers are not in the same format.
139    #[must_use]
140    pub fn difference(self, other: Float) -> (Float, Status) {
141        self.total(other, true)
142    }
143
144    /// `self * other`, rounded to nearest with ties to even.
145    ///
146    /// A zero times an infinity gives a nan and [`Status::INVALID`]. The sign is the two signs
147    /// multiplied, which a zero and a nan have as much as any other number does.
148    ///
149    /// # Panics
150    ///
151    /// If the two numbers are not in the same format.
152    #[must_use]
153    pub fn product(self, other: Float) -> (Float, Status) {
154        let format = self.agreed_format(other);
155        let sign = self.sign != other.sign;
156        if let Some(nan) = Float::propagated_nan(self, other) {
157            return nan;
158        }
159        match (self.category, other.category) {
160            (Category::Infinite, Category::Zero) | (Category::Zero, Category::Infinite) => {
161                (Float::nan(format), Status::INVALID)
162            }
163            (Category::Infinite, _) | (_, Category::Infinite) => {
164                (Float::infinity(format, sign), Status::NONE)
165            }
166            (Category::Zero, _) | (_, Category::Zero) => (Float::zero(format, sign), Status::NONE),
167            _ => {
168                let (left, left_exponent) = self.parts();
169                let (right, right_exponent) = other.parts();
170                let (high, low) = wide_multiply(left, right);
171                let exponent = left_exponent + right_exponent;
172                if high == 0 {
173                    return round(low, exponent, false, sign, format);
174                }
175                // Two significands of at most a hundred and thirteen bits make a product of at
176                // most two hundred and twenty six, so the count below is between one and ninety
177                // eight and every shift here has somewhere to go.
178                let drop = 128 - high.leading_zeros();
179                let sticky = low & ((1u128 << drop) - 1) != 0;
180                let significand = (high << (128 - drop)) | (low >> drop);
181                round(significand, exponent + drop as i32, sticky, sign, format)
182            }
183        }
184    }
185
186    /// `self / other`, rounded to nearest with ties to even.
187    ///
188    /// A finite number divided by zero gives an infinity and [`Status::DIVIDE_BY_ZERO`]. Zero
189    /// divided by zero and an infinity divided by an infinity both give a nan and
190    /// [`Status::INVALID`], which is the difference between a division that has no answer and one
191    /// whose answer is only too large to be a number.
192    ///
193    /// # Panics
194    ///
195    /// If the two numbers are not in the same format.
196    #[must_use]
197    pub fn quotient(self, other: Float) -> (Float, Status) {
198        let format = self.agreed_format(other);
199        let sign = self.sign != other.sign;
200        if let Some(nan) = Float::propagated_nan(self, other) {
201            return nan;
202        }
203        match (self.category, other.category) {
204            (Category::Infinite, Category::Infinite) | (Category::Zero, Category::Zero) => {
205                (Float::nan(format), Status::INVALID)
206            }
207            (Category::Infinite, _) => (Float::infinity(format, sign), Status::NONE),
208            (_, Category::Infinite) | (Category::Zero, _) => {
209                (Float::zero(format, sign), Status::NONE)
210            }
211            (_, Category::Zero) => (Float::infinity(format, sign), Status::DIVIDE_BY_ZERO),
212            _ => {
213                // Both significands are shifted up until their leading bit is the top bit of a
214                // `u128`, which puts their quotient between a half and two and so puts its
215                // leading bit in a known place. The quotient is then taken to two bits more than
216                // the format has, and whatever is left over is the sticky bit.
217                let (left, left_exponent) = self.parts();
218                let (right, right_exponent) = other.parts();
219                let (left_shift, right_shift) = (left.leading_zeros(), right.leading_zeros());
220                let extra = format.precision() + 2;
221                let numerator = left << left_shift;
222                let (quotient, remainder) = long_divide(numerator, right << right_shift, extra);
223                let exponent = (left_exponent - left_shift as i32)
224                    - (right_exponent - right_shift as i32)
225                    - extra as i32;
226                round(quotient, exponent, remainder != 0, sign, format)
227            }
228        }
229    }
230
231    /// How the two compare, or [`None`] if either is a nan and they do not compare at all.
232    ///
233    /// This is the comparison C's relational operators do, so a positive zero and a negative zero
234    /// are equal and the unordered case is the one that makes `x < y` and `!(x >= y)` different
235    /// questions.
236    ///
237    /// # Panics
238    ///
239    /// If the two numbers are not in the same format.
240    #[must_use]
241    pub fn compare(self, other: Float) -> Option<Ordering> {
242        self.agreed_format(other);
243        if self.is_nan() || other.is_nan() {
244            return None;
245        }
246        if self.is_zero() && other.is_zero() {
247            return Some(Ordering::Equal);
248        }
249        if self.sign != other.sign {
250            return Some(if self.sign { Ordering::Less } else { Ordering::Greater });
251        }
252        let magnitudes = self.compare_magnitude(other);
253        Some(if self.sign { magnitudes.reverse() } else { magnitudes })
254    }
255
256    /// The integer nearest this number in the direction given, as a number of the same format.
257    ///
258    /// This is C's `trunc`, `ceil`, `floor` and `round`, which differ in the direction alone. The
259    /// answer is always exact: an integer whose magnitude is at most this number's is a number the
260    /// format already holds, and rounding up cannot need a bit the format has not got, because the
261    /// only way a carry leaves the significand is when every kept bit was a one and the answer is
262    /// then a power of two. So nothing here can be inexact and nothing rounds twice.
263    ///
264    /// A nan, an infinity and a zero come back as they were, which is what the library functions
265    /// do. So does a number that is an integer already, including every number too large to have a
266    /// fraction at all. The sign survives in every case, so `ceil(-0.5)` is a negative zero and
267    /// not a positive one, which is the answer a rewriting into arithmetic would miss.
268    #[must_use]
269    pub fn to_integral(self, toward: Integral) -> Float {
270        let Category::Finite = self.category else { return self };
271        let (significand, exponent) = self.parts();
272        // A number scaled by a power of two that is not negative has no bits below the point.
273        if exponent >= 0 {
274            return self;
275        }
276        let dropped = exponent.unsigned_abs();
277        // Everything a hundred and twenty eight places below the point is smaller than any
278        // significand can carry back up, so the whole number is a fraction below a half.
279        let (kept, fraction, half) = if dropped >= 128 {
280            (0, true, false)
281        } else {
282            let rest = significand & ((1 << dropped) - 1);
283            (significand >> dropped, rest != 0, rest >= 1 << (dropped - 1))
284        };
285        if !fraction {
286            return self;
287        }
288        let away = match toward {
289            Integral::TowardZero => false,
290            Integral::Upward => !self.sign,
291            Integral::Downward => self.sign,
292            Integral::NearestTiesAway => half,
293        };
294        let magnitude = kept + u128::from(away);
295        if magnitude == 0 {
296            return Float::zero(self.format, self.sign);
297        }
298        // Exact, for the reason in the doc comment, so there is no status to hand back.
299        let (value, _) = Float::from_unsigned(magnitude, self.format);
300        value.with_sign(self.sign)
301    }
302
303    /// The larger of the two, which is C's `fmax`.
304    ///
305    /// The nan rule is the library's rather than the hardware's, and it is the reason this is not
306    /// the `maxsd` instruction with a different name: a nan beside a number gives the number, so
307    /// the function is a way to ignore one operand rather than a comparison. Two nans give a quiet
308    /// nan, since there is nothing else to hand back.
309    ///
310    /// Two zeros are decided by their signs, so a negative zero is the smaller, although the two
311    /// compare equal. 7.12.12.2 leaves that to the implementation and this is gcc's answer,
312    /// measured from what its own folding writes rather than read out of the manual.
313    ///
314    /// # Panics
315    ///
316    /// If the two numbers are not in the same format.
317    #[must_use]
318    pub fn larger(self, other: Float) -> Float {
319        self.pick(other, Ordering::Greater)
320    }
321
322    /// The smaller of the two, which is C's `fmin`, on the same terms as [`Float::larger`].
323    ///
324    /// # Panics
325    ///
326    /// If the two numbers are not in the same format.
327    #[must_use]
328    pub fn smaller(self, other: Float) -> Float {
329        self.pick(other, Ordering::Less)
330    }
331
332    /// Whichever of the two is on the side asked for.
333    fn pick(self, other: Float, want: Ordering) -> Float {
334        let format = self.agreed_format(other);
335        if self.is_nan() {
336            return if other.is_nan() { Float::nan(format) } else { other };
337        }
338        if other.is_nan() {
339            return self;
340        }
341        // Two zeros compare equal, so the comparison below would hand back whichever is second
342        // and the answer would depend on the order the operands were written in.
343        if self.is_zero() && other.is_zero() {
344            let wanted = matches!(want, Ordering::Less);
345            return if self.sign == wanted { self } else { other };
346        }
347        match self.compare(other) {
348            Some(order) if order == want => self,
349            _ => other,
350        }
351    }
352
353    /// The nearest number to this one in another format, rounded to nearest with ties to even.
354    ///
355    /// Widening is exact for every pair of formats here except a `__bf16` widened to a
356    /// `_Float16`, which has more precision and less range. Narrowing is what a cast does, and it
357    /// reports what it had to do to make the number fit.
358    #[must_use]
359    pub fn to_format(self, format: Format) -> (Float, Status) {
360        match self.category {
361            Category::Nan => (Float { sign: self.sign, ..Float::nan(format) }, Status::NONE),
362            Category::Infinite => (Float::infinity(format, self.sign), Status::NONE),
363            Category::Zero => (Float::zero(format, self.sign), Status::NONE),
364            Category::Finite => {
365                let (significand, exponent) = self.parts();
366                round(significand, exponent, false, self.sign, format)
367            }
368        }
369    }
370
371    /// The nearest number in `format` to a signed integer.
372    #[must_use]
373    pub fn from_signed(value: i128, format: Format) -> (Float, Status) {
374        if value == 0 {
375            return (Float::zero(format, false), Status::NONE);
376        }
377        round(value.unsigned_abs(), 0, false, value < 0, format)
378    }
379
380    /// The nearest number in `format` to an unsigned integer.
381    #[must_use]
382    pub fn from_unsigned(value: u128, format: Format) -> (Float, Status) {
383        if value == 0 {
384            return (Float::zero(format, false), Status::NONE);
385        }
386        round(value, 0, false, false, format)
387    }
388
389    /// The number truncated toward zero into an integer of `width` bits.
390    ///
391    /// What comes back is what an integer constant is stored as, which is the value sign extended
392    /// out of the type it has, so an unsigned conversion of a hundred and twenty eight bits comes
393    /// back with its top bit in the sign of the [`i128`].
394    ///
395    /// Converting a number that does not fit is undefined behaviour in C rather than a value, so
396    /// what comes back is the nearest end of the range together with [`Status::INVALID`], which
397    /// is what the caller warns about. A nan comes back as zero, for the same reason and with the
398    /// same flag. Dropping a fraction is [`Status::INEXACT`] and nothing worse, since that is the
399    /// conversion doing what it is for.
400    ///
401    /// # Panics
402    ///
403    /// If `width` is zero or wider than a hundred and twenty eight bits.
404    #[must_use]
405    pub fn to_integer(self, width: u32, signed: bool) -> (i128, Status) {
406        assert!(width > 0 && width <= 128, "an integer type of {width} bits");
407        let limit = self.limit(width, signed);
408        match self.category {
409            Category::Nan => (0, Status::INVALID),
410            Category::Infinite => (self.signed_value(limit), Status::INVALID),
411            Category::Zero => (0, Status::NONE),
412            Category::Finite => {
413                let (significand, exponent) = self.parts();
414                let (magnitude, inexact) = if exponent >= 0 {
415                    if exponent > significand.leading_zeros() as i32 {
416                        return (self.signed_value(limit), Status::INVALID);
417                    }
418                    (significand << exponent, false)
419                } else if -exponent >= 128 {
420                    (0, true)
421                } else {
422                    let dropped = -exponent as u32;
423                    (significand >> dropped, significand & ((1u128 << dropped) - 1) != 0)
424                };
425                if magnitude > limit {
426                    return (self.signed_value(limit), Status::INVALID);
427                }
428                let status = if inexact { Status::INEXACT } else { Status::NONE };
429                (self.signed_value(magnitude), status)
430            }
431        }
432    }
433
434    /// The largest magnitude an integer of this type can hold with this number's sign.
435    fn limit(self, width: u32, signed: bool) -> u128 {
436        match (signed, self.sign) {
437            (true, true) => 1u128 << (width - 1),
438            (true, false) => (1u128 << (width - 1)) - 1,
439            // An unsigned type has nowhere for a negative number to go, but truncating one whose
440            // magnitude is below one lands on zero, which is in range and is not an error.
441            (false, true) => 0,
442            (false, false) => u128::MAX >> (128 - width),
443        }
444    }
445
446    /// A magnitude given this number's sign, as an integer constant is stored.
447    fn signed_value(self, magnitude: u128) -> i128 {
448        if self.sign { (magnitude as i128).wrapping_neg() } else { magnitude as i128 }
449    }
450
451    /// The significand and the power of two it is scaled by, so that the value of a finite number
452    /// is the first of these shifted by the second.
453    fn parts(self) -> (u128, i32) {
454        (self.significand, self.exponent - self.format.precision() as i32 + 1)
455    }
456
457    /// The format both numbers are in.
458    ///
459    /// # Panics
460    ///
461    /// If they are not in the same one. Every operation here is on two numbers of one type,
462    /// because the usual arithmetic conversions ran first, and converting one here instead would
463    /// silently round an operand on the way in.
464    fn agreed_format(self, other: Float) -> Format {
465        assert_eq!(self.format, other.format, "an operation on two floating formats at once");
466        self.format
467    }
468
469    /// The nan an operation gives when an operand is one, if either is.
470    fn propagated_nan(left: Float, right: Float) -> Option<(Float, Status)> {
471        (left.is_nan() || right.is_nan()).then(|| (Float::nan(left.format), Status::NONE))
472    }
473
474    /// How the magnitudes of two numbers in the same format compare, nans aside.
475    ///
476    /// Comparing the exponent before the significand works across the subnormals as well as the
477    /// normals, because a subnormal has the smallest exponent there is and a leading zero where a
478    /// normal number has its leading one.
479    fn compare_magnitude(self, other: Float) -> Ordering {
480        match (self.category, other.category) {
481            (Category::Zero, Category::Zero) | (Category::Infinite, Category::Infinite) => {
482                Ordering::Equal
483            }
484            (Category::Zero, _) | (_, Category::Infinite) => Ordering::Less,
485            (Category::Infinite, _) | (_, Category::Zero) => Ordering::Greater,
486            _ => (self.exponent, self.significand).cmp(&(other.exponent, other.significand)),
487        }
488    }
489
490    /// The sum of two numbers, or their difference, which is the sum of one of them and the other
491    /// negated and is not a separate operation anywhere below this line.
492    fn total(self, other: Float, subtract: bool) -> (Float, Status) {
493        let format = self.agreed_format(other);
494        let other = if subtract { other.negated() } else { other };
495        if let Some(nan) = Float::propagated_nan(self, other) {
496            return nan;
497        }
498        match (self.category, other.category) {
499            (Category::Infinite, Category::Infinite) => {
500                if self.sign == other.sign {
501                    (self, Status::NONE)
502                } else {
503                    (Float::nan(format), Status::INVALID)
504                }
505            }
506            (Category::Infinite, _) => (self, Status::NONE),
507            (_, Category::Infinite) => (other, Status::NONE),
508            // Round to nearest makes the sum of two zeros positive unless both of them were
509            // negative, which is the one rule here that is about the sign rather than the value.
510            (Category::Zero, Category::Zero) => {
511                (Float::zero(format, self.sign && other.sign), Status::NONE)
512            }
513            (Category::Zero, _) => (other, Status::NONE),
514            (_, Category::Zero) => (self, Status::NONE),
515            _ => {
516                let (big, small) = if self.compare_magnitude(other) == Ordering::Less {
517                    (other, self)
518                } else {
519                    (self, other)
520                };
521                let (left, exponent) = big.parts();
522                let (right, small_exponent) = small.parts();
523                let distance = (exponent - small_exponent) as u32;
524                let left = left << GUARD;
525                let (mut right, sticky) = if distance <= GUARD {
526                    (right << (GUARD - distance), false)
527                } else if distance - GUARD >= 128 {
528                    (0, true)
529                } else {
530                    let dropped = distance - GUARD;
531                    (right >> dropped, right & ((1u128 << dropped) - 1) != 0)
532                };
533                let exponent = exponent - GUARD as i32;
534                if big.sign == small.sign {
535                    return round(left + right, exponent, sticky, big.sign, format);
536                }
537                // What was dropped belongs to the number being taken away, so the answer is a
538                // little below what the bits that are left say it is. Taking one more off, with
539                // the sticky bit set, says exactly that: the answer is between the two, which is
540                // all the rounding needs. It cannot go below zero, because the two are ordered by
541                // magnitude and a dropped bit means the smaller one is smaller by more than the
542                // last bit of the larger.
543                right += u128::from(sticky);
544                if left == right {
545                    return (Float::zero(format, false), Status::NONE);
546                }
547                round(left - right, exponent, sticky, big.sign, format)
548            }
549        }
550    }
551}
552
553/// The full two hundred and fifty six bit product of two numbers, high half first.
554///
555/// The halves of each operand multiply into products that fit, and the middle column is the one
556/// that has to be carried by hand. There is no `u256` and no widening multiply in the language,
557/// so this is what multiplying two significands looks like.
558fn wide_multiply(left: u128, right: u128) -> (u128, u128) {
559    const LOW: u128 = u64::MAX as u128;
560    let (left_low, left_high) = (left & LOW, left >> 64);
561    let (right_low, right_high) = (right & LOW, right >> 64);
562    let low = left_low * right_low;
563    let first = left_low * right_high;
564    let second = left_high * right_low;
565    let middle = (low >> 64) + (first & LOW) + (second & LOW);
566    let high = left_high * right_high + (first >> 64) + (second >> 64) + (middle >> 64);
567    (high, (middle << 64) | (low & LOW))
568}
569
570/// The quotient of `numerator` shifted up by `extra` bits and `divisor`, and what is left over.
571///
572/// Both arguments have their top bit set, so their quotient is between a half and two and the
573/// answer here has either `extra` or `extra` plus one bits. Restoring division a bit at a time,
574/// because the alternatives are a longer program and this runs once per constant folded.
575fn long_divide(numerator: u128, divisor: u128, extra: u32) -> (u128, u128) {
576    let mut remainder = 0u128;
577    let mut quotient = 0u128;
578    for step in 0..128 + extra {
579        let bit = if step < 128 { (numerator >> (127 - step)) & 1 } else { 0 };
580        // The remainder is below the divisor, so doubling it can carry out of the top of a `u128`
581        // and still be a number the divisor goes into exactly once.
582        let carry = remainder >> 127 == 1;
583        remainder = (remainder << 1) | bit;
584        quotient <<= 1;
585        if carry || remainder >= divisor {
586            remainder = remainder.wrapping_sub(divisor);
587            quotient |= 1;
588        }
589    }
590    (quotient, remainder)
591}
592
593#[cfg(test)]
594mod tests {
595    use super::*;
596
597    /// A `double` from the host's bits, which is what makes the host an oracle.
598    fn double(value: f64) -> Float {
599        Float::from_bits(Format::Double, u128::from(value.to_bits()))
600    }
601
602    /// The host number a `double` holds.
603    fn host(value: Float) -> f64 {
604        f64::from_bits(value.to_bits() as u64)
605    }
606
607    fn single(value: f32) -> Float {
608        Float::from_bits(Format::Single, u128::from(value.to_bits()))
609    }
610
611    fn host_single(value: Float) -> f32 {
612        f32::from_bits(value.to_bits() as u32)
613    }
614
615    /// A fixed sequence, so that a failure names the same numbers on every machine.
616    fn next(state: &mut u64) -> u64 {
617        *state = state.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
618        *state
619    }
620
621    /// Every operation on a pair of `double` values, against what the host computes.
622    fn agrees(left: f64, right: f64) {
623        let (a, b) = (double(left), double(right));
624        for (name, mine, theirs) in [
625            ("+", a.sum(b).0, left + right),
626            ("-", a.difference(b).0, left - right),
627            ("*", a.product(b).0, left * right),
628            ("/", a.quotient(b).0, left / right),
629        ] {
630            if theirs.is_nan() {
631                assert!(mine.is_nan(), "{left:e} {name} {right:e} gave {}", host(mine));
632            } else {
633                assert_eq!(
634                    host(mine).to_bits(),
635                    theirs.to_bits(),
636                    "{left:e} {name} {right:e} gave {} not {theirs:e}",
637                    host(mine)
638                );
639            }
640        }
641    }
642
643    /// The same, for a pair of `float` values.
644    fn agrees_single(left: f32, right: f32) {
645        let (a, b) = (single(left), single(right));
646        for (name, mine, theirs) in [
647            ("+", a.sum(b).0, left + right),
648            ("-", a.difference(b).0, left - right),
649            ("*", a.product(b).0, left * right),
650            ("/", a.quotient(b).0, left / right),
651        ] {
652            if theirs.is_nan() {
653                assert!(mine.is_nan(), "{left:e} {name} {right:e}");
654            } else {
655                assert_eq!(
656                    host_single(mine).to_bits(),
657                    theirs.to_bits(),
658                    "{left:e} {name} {right:e} gave {} not {theirs:e}",
659                    host_single(mine)
660                );
661            }
662        }
663    }
664
665    #[test]
666    fn the_ordinary_sums_are_the_ones_the_host_computes() {
667        for (left, right) in [
668            (1.0, 1.0),
669            (1.0, 2.0),
670            (0.1, 0.2),
671            (1.0, -1.0),
672            (1e308, 1e308),
673            (1.0, 1e-308),
674            (3.0, 7.0),
675            (1.0, 3.0),
676            (2.5, 0.5),
677            (1e-320, 1e-320),
678            (f64::MAX, f64::MIN),
679        ] {
680            agrees(left, right);
681            agrees(right, left);
682            agrees(-left, right);
683            agrees(left, -right);
684        }
685    }
686
687    #[test]
688    fn a_sweep_of_random_doubles_agrees_with_the_host_in_every_bit() {
689        // Random bits cover the infinities, the nans and the subnormals as well as the ordinary
690        // numbers, which is the point of taking bits rather than taking values.
691        let mut state = 0x2545_f491_4f6c_dd1du64;
692        for _ in 0..20_000 {
693            agrees(f64::from_bits(next(&mut state)), f64::from_bits(next(&mut state)));
694        }
695    }
696
697    #[test]
698    fn a_sweep_of_random_floats_agrees_with_the_host_in_every_bit() {
699        let mut state = 0x1234_5678_9abc_def0u64;
700        for _ in 0..20_000 {
701            let bits = next(&mut state);
702            agrees_single(f32::from_bits(bits as u32), f32::from_bits((bits >> 32) as u32));
703        }
704    }
705
706    #[test]
707    fn a_sweep_of_numbers_close_together_agrees_too() {
708        // Two numbers of nearly the same size are where a subtraction cancels and where the bits
709        // that are left come from the guard bits rather than from either operand.
710        let mut state = 0x9e37_79b9_7f4a_7c15u64;
711        for _ in 0..20_000 {
712            let left = (next(&mut state) >> 11) as f64;
713            let scale = f64::from(next(&mut state) as u32 % 8) - 4.0;
714            let right = (next(&mut state) >> 11) as f64 * scale.exp2();
715            agrees(left, right);
716            agrees(left, left);
717            agrees(left, -left);
718        }
719    }
720
721    #[test]
722    fn the_operations_with_no_answer_say_so() {
723        let (infinity, zero) = (Float::infinity(Format::Double, false), double(0.0));
724        let (one, nan) = (double(1.0), Float::nan(Format::Double));
725
726        let (value, status) = infinity.difference(infinity);
727        assert!(value.is_nan() && status.has(Status::INVALID));
728        let (value, status) = infinity.product(zero);
729        assert!(value.is_nan() && status.has(Status::INVALID));
730        let (value, status) = zero.quotient(zero);
731        assert!(value.is_nan() && status.has(Status::INVALID));
732        let (value, status) = infinity.quotient(infinity);
733        assert!(value.is_nan() && status.has(Status::INVALID));
734
735        // A division by zero has an answer, which is why it is not the same flag.
736        let (value, status) = one.quotient(zero);
737        assert!(value.is_infinite() && !value.is_negative());
738        assert!(status.has(Status::DIVIDE_BY_ZERO) && !status.has(Status::INVALID));
739        assert!(one.negated().quotient(zero).0.is_negative());
740        assert!(one.quotient(zero.negated()).0.is_negative());
741
742        // A nan on the way in is a nan on the way out, and nothing is reported for it.
743        for (value, status) in
744            [nan.sum(one), one.sum(nan), nan.product(one), nan.quotient(one), one.difference(nan)]
745        {
746            assert!(value.is_nan() && status.is_none());
747        }
748        assert!(infinity.sum(infinity).0.is_infinite());
749        assert!(infinity.sum(one).0.is_infinite());
750    }
751
752    #[test]
753    fn the_sign_of_a_zero_is_the_one_the_host_gives() {
754        let (positive, negative) = (double(0.0), double(-0.0));
755        for (mine, theirs) in [
756            (positive.sum(positive), 0.0 + 0.0),
757            (positive.sum(negative), 0.0 + -0.0),
758            (negative.sum(positive), -0.0 + 0.0),
759            (negative.sum(negative), -0.0 + -0.0),
760            (positive.difference(positive), 0.0 - 0.0),
761            (negative.difference(positive), -0.0 - 0.0),
762            (double(1.0).difference(double(1.0)), 1.0 - 1.0),
763            (double(-1.0).sum(double(1.0)), -1.0 + 1.0),
764            (positive.product(double(3.0)), 0.0 * 3.0),
765            (negative.product(double(3.0)), -0.0 * 3.0),
766            (positive.quotient(double(-3.0)), 0.0 / -3.0),
767        ] {
768            assert_eq!(host(mine.0).to_bits(), f64::to_bits(theirs), "{theirs}");
769        }
770    }
771
772    #[test]
773    fn an_operation_says_what_it_had_to_do_to_the_answer() {
774        let (one, three) = (double(1.0), double(3.0));
775        assert!(one.sum(one).1.is_none());
776        assert!(one.product(three).1.is_none());
777        assert!(one.quotient(double(2.0)).1.is_none());
778        assert!(one.quotient(three).1.has(Status::INEXACT));
779
780        let (value, status) = double(f64::MAX).product(double(2.0));
781        assert!(value.is_infinite() && status.has(Status::OVERFLOW) && status.has(Status::INEXACT));
782        let (value, status) = double(f64::MIN_POSITIVE).quotient(double(1e300));
783        assert!(value.is_zero() && status.has(Status::UNDERFLOW) && status.has(Status::INEXACT));
784        // A subnormal answer that lost no bits is exact, small as it is.
785        let four = Float::from_bits(Format::Double, 4);
786        assert!(four.quotient(double(2.0)).1.is_none());
787        assert!(four.quotient(double(4.0)).1.is_none());
788        // One that lost a bit is inexact and underflowed, both.
789        let status = Float::from_bits(Format::Double, 3).quotient(double(2.0)).1;
790        assert!(status.has(Status::INEXACT) && status.has(Status::UNDERFLOW));
791    }
792
793    #[test]
794    fn a_comparison_orders_the_numbers_and_leaves_the_nans_out() {
795        let (one, two) = (double(1.0), double(2.0));
796        assert_eq!(one.compare(two), Some(Ordering::Less));
797        assert_eq!(two.compare(one), Some(Ordering::Greater));
798        assert_eq!(one.compare(one), Some(Ordering::Equal));
799        assert_eq!(one.negated().compare(two.negated()), Some(Ordering::Greater));
800        assert_eq!(one.negated().compare(one), Some(Ordering::Less));
801        // The two zeros are the same number as far as a comparison is concerned.
802        assert_eq!(double(0.0).compare(double(-0.0)), Some(Ordering::Equal));
803        assert_eq!(double(-0.0).compare(double(0.0)), Some(Ordering::Equal));
804        assert_eq!(double(-0.0).compare(one), Some(Ordering::Less));
805        // An infinity is at the end of the order, and a nan is not in the order at all.
806        let infinity = Float::infinity(Format::Double, false);
807        assert_eq!(infinity.compare(double(f64::MAX)), Some(Ordering::Greater));
808        assert_eq!(infinity.negated().compare(double(f64::MIN)), Some(Ordering::Less));
809        assert_eq!(infinity.compare(infinity), Some(Ordering::Equal));
810        let nan = Float::nan(Format::Double);
811        assert_eq!(nan.compare(one), None);
812        assert_eq!(one.compare(nan), None);
813        assert_eq!(nan.compare(nan), None);
814    }
815
816    #[test]
817    fn a_comparison_of_random_numbers_is_the_host_order() {
818        let mut state = 0xdead_beef_cafe_f00du64;
819        for _ in 0..20_000 {
820            let left = f64::from_bits(next(&mut state));
821            let right = f64::from_bits(next(&mut state));
822            assert_eq!(
823                double(left).compare(double(right)),
824                left.partial_cmp(&right),
825                "{left:e} against {right:e}"
826            );
827        }
828    }
829
830    #[test]
831    fn a_conversion_between_formats_rounds_the_way_the_host_does() {
832        let mut state = 0x0123_4567_89ab_cdefu64;
833        for _ in 0..20_000 {
834            let value = f64::from_bits(next(&mut state));
835            let narrowed = double(value).to_format(Format::Single);
836            let theirs = value as f32;
837            if theirs.is_nan() {
838                assert!(narrowed.0.is_nan(), "{value:e}");
839                continue;
840            }
841            assert_eq!(host_single(narrowed.0).to_bits(), theirs.to_bits(), "{value:e}");
842            // Widening is exact, so the number that comes back is the one that went in.
843            let widened = narrowed.0.to_format(Format::Double);
844            assert_eq!(host(widened.0).to_bits(), f64::from(theirs).to_bits(), "{value:e}");
845            assert!(widened.1.is_none(), "{value:e}");
846        }
847    }
848
849    #[test]
850    fn a_narrowing_conversion_says_what_it_did() {
851        let (value, status) = double(0.1).to_format(Format::Single);
852        assert_eq!(host_single(value).to_bits(), (0.1f32).to_bits());
853        assert!(status.has(Status::INEXACT));
854        assert!(double(0.5).to_format(Format::Single).1.is_none());
855        let (value, status) = double(1e300).to_format(Format::Single);
856        assert!(value.is_infinite() && status.has(Status::OVERFLOW));
857        let (value, status) = double(1e-300).to_format(Format::Single);
858        assert!(value.is_zero() && status.has(Status::UNDERFLOW));
859        // The x87 format has more bits than a `double`, so a number goes up into it exactly and
860        // comes back down as the number it started as.
861        let (up, status) = double(0.1).to_format(Format::X87Extended);
862        assert!(status.is_none());
863        assert_eq!(up.to_bits(), 0x3ffb_cccc_cccc_cccc_d000);
864        assert_eq!(host(up.to_format(Format::Double).0).to_bits(), (0.1f64).to_bits());
865        // Widening keeps the error the number already had rather than removing it: a tenth that
866        // went through a `double` is not the tenth an x87 number can hold.
867        let tenth = Float::parse("0.1", Format::X87Extended).expect("a tenth").0;
868        assert_eq!(tenth.to_bits(), 0x3ffb_cccc_cccc_cccc_cccd);
869        assert_ne!(up.to_bits(), tenth.to_bits());
870    }
871
872    #[test]
873    fn an_integer_becomes_the_nearest_number_to_it() {
874        let mut state = 0xfeed_face_dead_c0dcu64;
875        for _ in 0..20_000 {
876            let value = next(&mut state) as i64;
877            let mine = Float::from_signed(i128::from(value), Format::Double).0;
878            assert_eq!(host(mine).to_bits(), (value as f64).to_bits(), "{value}");
879            let value = next(&mut state);
880            let mine = Float::from_unsigned(u128::from(value), Format::Single).0;
881            assert_eq!(host_single(mine).to_bits(), (value as f32).to_bits(), "{value}");
882        }
883        // The ends of the two widest integer types, which are where the rounding shows.
884        assert_eq!(host(Float::from_signed(0, Format::Double).0).to_bits(), (0f64).to_bits());
885        assert!(Float::from_signed(1 << 52, Format::Double).1.is_none());
886        assert!(Float::from_signed((1 << 53) + 1, Format::Double).1.has(Status::INEXACT));
887        let (value, status) = Float::from_signed(i128::MIN, Format::Double);
888        assert!(value.is_negative() && status.is_none());
889        assert_eq!(host(value), -(2f64).powi(127));
890        let (value, status) = Float::from_unsigned(u128::MAX, Format::Double);
891        assert!(status.has(Status::INEXACT));
892        assert_eq!(host(value), (2f64).powi(128));
893    }
894
895    #[test]
896    fn a_number_becomes_an_integer_by_dropping_its_fraction() {
897        for (value, expected) in [
898            (1.5, 1),
899            (-1.5, -1),
900            (0.9, 0),
901            (-0.9, 0),
902            (2.0, 2),
903            (-2.0, -2),
904            (1e18, 1_000_000_000_000_000_000),
905        ] {
906            assert_eq!(double(value).to_integer(64, true).0, expected, "{value}");
907        }
908        assert!(double(2.0).to_integer(64, true).1.is_none());
909        assert!(double(1.5).to_integer(64, true).1.has(Status::INEXACT));
910        // Truncation toward zero lands inside an unsigned type, and anything below it does not.
911        assert_eq!(double(-0.5).to_integer(32, false), (0, Status::INEXACT));
912        let (value, status) = double(-1.0).to_integer(32, false);
913        assert!(value == 0 && status.has(Status::INVALID));
914    }
915
916    #[test]
917    fn a_number_that_will_not_fit_gives_the_end_of_the_range() {
918        let (value, status) = double(1e30).to_integer(32, true);
919        assert!(value == i128::from(i32::MAX) && status.has(Status::INVALID));
920        let (value, status) = double(-1e30).to_integer(32, true);
921        assert!(value == i128::from(i32::MIN) && status.has(Status::INVALID));
922        let (value, status) = double(1e30).to_integer(32, false);
923        assert!(value == i128::from(u32::MAX) && status.has(Status::INVALID));
924        let (value, status) = Float::infinity(Format::Double, false).to_integer(64, true);
925        assert!(value == i128::from(i64::MAX) && status.has(Status::INVALID));
926        let (value, status) = Float::nan(Format::Double).to_integer(64, true);
927        assert!(value == 0 && status.has(Status::INVALID));
928        // The widest unsigned type has its top bit where the sign of the value holding it is.
929        let (value, status) = double(f64::MAX).to_integer(128, false);
930        assert!(value == -1 && status.has(Status::INVALID));
931        // The widest signed one holds its own smallest number exactly.
932        let smallest = double(-(2f64).powi(127));
933        assert_eq!(smallest.to_integer(128, true), (i128::MIN, Status::NONE));
934    }
935
936    #[test]
937    fn a_conversion_to_an_integer_is_the_one_the_host_does() {
938        // Rust's own conversion saturates and turns a nan into zero, which is what C leaves
939        // undefined and what this fills it in with, so the host answers for this too.
940        let mut state = 0xabad_1dea_0000_0001u64;
941        for _ in 0..20_000 {
942            let value = f64::from_bits(next(&mut state));
943            assert_eq!(double(value).to_integer(64, true).0, i128::from(value as i64), "{value:e}");
944            assert_eq!(
945                double(value).to_integer(32, false).0,
946                i128::from(value as u32),
947                "{value:e}"
948            );
949        }
950    }
951
952    #[test]
953    fn the_wide_formats_compute_what_they_are_supposed_to() {
954        let quad = |text: &str| Float::parse(text, Format::Quad).expect("a number").0;
955        // A third in binary128 is the exact quotient rounded down, since the digits repeat and
956        // the first one dropped is below a half. Worked out by hand rather than measured, because
957        // no host here has the format.
958        let (third, status) = quad("1").quotient(quad("3"));
959        assert_eq!(third.to_bits(), 0x3ffd_5555_5555_5555_5555_5555_5555_5555);
960        assert!(status.has(Status::INEXACT));
961        // Three of them is one exactly, because the sum is a tie and the tie rounds up.
962        let (whole, status) = third.sum(third).0.sum(third);
963        assert_eq!(whole.to_bits(), quad("1").to_bits());
964        assert!(status.has(Status::INEXACT));
965
966        // The x87 format has sixty four bits of significand, so this is exact where a `double`
967        // would have to round it.
968        let x87 = |text: &str| Float::parse(text, Format::X87Extended).expect("a number").0;
969        let (sum, status) = x87("9007199254740993").sum(x87("1"));
970        assert!(status.is_none());
971        assert_eq!(sum.to_bits(), x87("9007199254740994").to_bits());
972
973        // Half precision has eleven, so 2049 is a tie between the two numbers either side of it
974        // and rounds to the even one below.
975        let half = |text: &str| Float::parse(text, Format::Half).expect("a number").0;
976        let (value, status) = half("2048").sum(half("1"));
977        assert!(status.has(Status::INEXACT));
978        assert_eq!(value.to_bits(), half("2048").to_bits());
979    }
980
981    #[test]
982    fn a_nan_survives_a_trip_through_its_encoding() {
983        for format in [
984            Format::Half,
985            Format::BFloat16,
986            Format::Single,
987            Format::Double,
988            Format::X87Extended,
989            Format::Quad,
990        ] {
991            let nan = Float::nan(format);
992            assert!(nan.is_nan() && !nan.is_finite() && !nan.is_infinite(), "{format:?}");
993            assert_eq!(Float::from_bits(format, nan.to_bits()), nan, "{format:?}");
994            assert_eq!(nan.negated().to_hex(), "-nan", "{format:?}");
995            // An infinity is not a nan, in the format that stores the bit above the fraction as
996            // well as in the ones that leave it implied.
997            let infinity = Float::infinity(format, false);
998            assert!(Float::from_bits(format, infinity.to_bits()).is_infinite(), "{format:?}");
999        }
1000        // The host agrees about where the quiet bit is.
1001        assert_eq!(Float::nan(Format::Double).to_bits(), u128::from(f64::NAN.to_bits()));
1002        assert!(Float::from_bits(Format::Double, u128::from(f64::NAN.to_bits())).is_nan());
1003    }
1004
1005    /// The host is the oracle again, and its `round` is C's: a half goes away from zero rather
1006    /// than to even, which is the one place C and IEEE's default disagree.
1007    #[test]
1008    fn a_number_taken_to_an_integer_lands_where_the_host_puts_it() {
1009        let mut state = 0x5eed_1234_u64;
1010        for _ in 0..20000 {
1011            let bits = next(&mut state);
1012            let value = f64::from_bits(bits);
1013            if !value.is_finite() {
1014                continue;
1015            }
1016            for (name, toward, theirs) in [
1017                ("trunc", Integral::TowardZero, value.trunc()),
1018                ("ceil", Integral::Upward, value.ceil()),
1019                ("floor", Integral::Downward, value.floor()),
1020                ("round", Integral::NearestTiesAway, value.round()),
1021            ] {
1022                let mine = double(value).to_integral(toward);
1023                assert_eq!(
1024                    host(mine).to_bits(),
1025                    theirs.to_bits(),
1026                    "{name} of {value:e} gave {}",
1027                    host(mine)
1028                );
1029            }
1030        }
1031    }
1032
1033    /// The small numbers, where the answer is a zero whose sign is the only thing left of the
1034    /// number that went in, and the large ones, which have no fraction to take.
1035    #[test]
1036    fn the_sign_of_a_number_rounded_away_to_nothing_is_still_there() {
1037        let cases: &[(f64, Integral, f64)] = &[
1038            (-0.5, Integral::Upward, -0.0),
1039            (-0.2, Integral::Upward, -0.0),
1040            (-0.5, Integral::TowardZero, -0.0),
1041            (0.5, Integral::Downward, 0.0),
1042            (0.4, Integral::NearestTiesAway, 0.0),
1043            (-0.4, Integral::NearestTiesAway, -0.0),
1044            (-0.0, Integral::Upward, -0.0),
1045            (0.5, Integral::NearestTiesAway, 1.0),
1046            (-0.5, Integral::NearestTiesAway, -1.0),
1047            (2.5, Integral::NearestTiesAway, 3.0),
1048            (-2.5, Integral::NearestTiesAway, -3.0),
1049            (1e300, Integral::Upward, 1e300),
1050            (f64::MIN_POSITIVE / 4.0, Integral::Downward, 0.0),
1051            (-f64::MIN_POSITIVE / 4.0, Integral::Upward, -0.0),
1052        ];
1053        for &(value, toward, want) in cases {
1054            let mine = double(value).to_integral(toward);
1055            assert_eq!(host(mine).to_bits(), want.to_bits(), "{toward:?} of {value:e}");
1056        }
1057        // A nan and an infinity come back as they were, which no host call is needed to say.
1058        assert!(double(f64::NAN).to_integral(Integral::Upward).is_nan());
1059        let infinity = double(f64::NEG_INFINITY).to_integral(Integral::Upward);
1060        assert!(infinity.is_infinite() && infinity.is_negative());
1061    }
1062
1063    /// Every format, since the significand and the exponent are the only things the operation
1064    /// reads and the four formats keep them in four different places.
1065    #[test]
1066    fn a_half_is_taken_to_an_integer_in_every_format() {
1067        for format in
1068            [Format::Half, Format::Single, Format::Double, Format::X87Extended, Format::Quad]
1069        {
1070            let (half, _) = Float::parse("2.5", format).expect("a number");
1071            let (three, _) = Float::parse("3", format).expect("a number");
1072            let (two, _) = Float::parse("2", format).expect("a number");
1073            assert_eq!(half.to_integral(Integral::Upward), three, "{format:?}");
1074            assert_eq!(half.to_integral(Integral::TowardZero), two, "{format:?}");
1075            assert_eq!(half.to_integral(Integral::NearestTiesAway), three, "{format:?}");
1076            assert_eq!(
1077                half.negated().to_integral(Integral::Downward),
1078                three.negated(),
1079                "{format:?}"
1080            );
1081        }
1082    }
1083
1084    /// The values gcc 16.2.0 folds these to, including the two the standard leaves open.
1085    #[test]
1086    fn the_larger_of_two_is_the_one_the_library_would_return() {
1087        let (one, two) = (double(1.0), double(2.0));
1088        assert_eq!(host(one.larger(two)), 2.0);
1089        assert_eq!(host(one.smaller(two)), 1.0);
1090        assert_eq!(host(two.larger(one)), 2.0);
1091        assert_eq!(host(two.smaller(one)), 1.0);
1092        // A nan is ignored whichever side it is on, which is the rule that makes these library
1093        // functions rather than the machine's comparison.
1094        let nan = double(f64::NAN);
1095        assert_eq!(host(nan.larger(two)), 2.0);
1096        assert_eq!(host(two.larger(nan)), 2.0);
1097        assert_eq!(host(nan.smaller(two)), 2.0);
1098        assert!(nan.larger(nan).is_nan());
1099        // Two zeros are ordered by their signs although they compare equal.
1100        let (zero, minus) = (double(0.0), double(-0.0));
1101        let zeros: &[(&str, Float, f64)] = &[
1102            ("fmax(0, -0)", zero.larger(minus), 0.0),
1103            ("fmax(-0, 0)", minus.larger(zero), 0.0),
1104            ("fmin(0, -0)", zero.smaller(minus), -0.0),
1105            ("fmin(-0, 0)", minus.smaller(zero), -0.0),
1106        ];
1107        for &(name, mine, want) in zeros {
1108            assert_eq!(host(mine).to_bits(), want.to_bits(), "{name}");
1109        }
1110        // An infinity is the end of the range and not a special case.
1111        let infinity = double(f64::INFINITY);
1112        assert!(infinity.larger(two).is_infinite());
1113        assert_eq!(host(infinity.smaller(two)), 2.0);
1114    }
1115
1116    #[test]
1117    fn the_helpers_underneath_do_what_they_say() {
1118        assert_eq!(wide_multiply(0, 12345), (0, 0));
1119        assert_eq!(wide_multiply(3, 5), (0, 15));
1120        assert_eq!(wide_multiply(1, u128::MAX), (0, u128::MAX));
1121        assert_eq!(wide_multiply(u128::MAX, u128::MAX), (u128::MAX - 1, 1));
1122        assert_eq!(wide_multiply(1 << 127, 1 << 127), (1 << 126, 0));
1123        // A number divided by itself is one, at whatever scale the extra bits put it.
1124        assert_eq!(long_divide(1 << 127, 1 << 127, 4), (16, 0));
1125        assert_eq!(long_divide(3 << 126, 1 << 127, 4), (24, 0));
1126        assert_eq!(long_divide(1 << 127, 3 << 126, 4), (10, 1 << 127));
1127    }
1128}