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