compiler_builtins/float/
div.rs

1//! Floating point division routines.
2//!
3//! This module documentation gives an overview of the method used. More documentation is inline.
4//!
5//! # Relevant notation
6//!
7//! - `m_a`: the mantissa of `a`, in base 2
8//! - `p_a`: the exponent of `a`, in base 2. I.e. `a = m_a * 2^p_a`
9//! - `uqN` (e.g. `uq1`): this refers to Q notation for fixed-point numbers. UQ1.31 is an unsigned
10//!   fixed-point number with 1 integral bit, and 31 decimal bits. A `uqN` variable of type `uM`
11//!   will have N bits of integer and M-N bits of fraction.
12//! - `hw`: half width, i.e. for `f64` this will be a `u32`.
13//! - `x` is the best estimate of `1/m_b`
14//!
15//! # Method Overview
16//!
17//! Division routines must solve for `a / b`, which is `res = m_a*2^p_a / m_b*2^p_b`. The basic
18//! process is as follows:
19//!
20//! - Rearange the exponent and significand to simplify the operations:
21//!   `res = (m_a / m_b) * 2^{p_a - p_b}`.
22//! - Check for early exits (infinity, zero, etc).
23//! - If `a` or `b` are subnormal, normalize by shifting the mantissa and adjusting the exponent.
24//! - Set the implicit bit so math is correct.
25//! - Shift mantissa significant digits (with implicit bit) fully left such that fixed-point UQ1
26//!   or UQ0 numbers can be used for mantissa math. These will have greater precision than the
27//!   actual mantissa, which is important for correct rounding.
28//! - Calculate the reciprocal of `m_b`, `x`.
29//! - Use the reciprocal to multiply rather than divide: `res = m_a * x_b * 2^{p_a - p_b}`.
30//! - Reapply rounding.
31//!
32//! # Reciprocal calculation
33//!
34//! Calculating the reciprocal is the most complicated part of this process. It uses the
35//! [Newton-Raphson method], which picks an initial estimation (of the reciprocal) and performs
36//! a number of iterations to increase its precision.
37//!
38//! In general, Newton's method takes the following form:
39//!
40//! ```text
41//! `x_n` is a guess or the result of a previous iteration. Increasing `n` converges to the
42//! desired result.
43//!
44//! The result approaches a zero of `f(x)` by applying a correction to the previous gues.
45//!
46//! x_{n+1} = x_n - f(x_n) / f'(x_n)
47//! ```
48//!
49//! Applying this to find the reciprocal:
50//!
51//! ```text
52//! 1 / x = b
53//!
54//! Rearrange so we can solve by finding a zero
55//! 0 = (1 / x) - b = f(x)
56//!
57//! f'(x) = -x^{-2}
58//!
59//! x_{n+1} = 2*x_n - b*x_n^2
60//! ```
61//!
62//! This is a process that can be repeated to calculate the reciprocal with enough precision to
63//! achieve a correctly rounded result for the overall division operation. The maximum required
64//! number of iterations is known since precision doubles with each iteration.
65//!
66//! # Half-width operations
67//!
68//! Calculating the reciprocal requires widening multiplication and performing arithmetic on the
69//! results, meaning that emulated integer arithmetic on `u128` (for `f64`) and `u256` (for `f128`)
70//! gets used instead of native math.
71//!
72//! To make this more efficient, all but the final operation can be computed using half-width
73//! integers. For example, rather than computing four iterations using 128-bit integers for `f64`,
74//! we can instead perform three iterations using native 64-bit integers and only one final
75//! iteration using the full 128 bits.
76//!
77//! This works because of precision doubling. Some leeway is allowed here because the fixed-point
78//! number has more bits than the final mantissa will.
79//!
80//! [Newton-Raphson method]: https://en.wikipedia.org/wiki/Newton%27s_method
81
82use core::mem::size_of;
83use core::ops;
84
85use super::HalfRep;
86use crate::float::Float;
87use crate::int::{CastFrom, CastInto, DInt, HInt, Int, MinInt};
88
89fn div<F: Float>(a: F, b: F) -> F
90where
91    F::Int: CastInto<i32>,
92    F::Int: From<HalfRep<F>>,
93    F::Int: From<u8>,
94    F::Int: HInt + DInt,
95    <F::Int as HInt>::D: ops::Shr<u32, Output = <F::Int as HInt>::D>,
96    F::Int: From<u32>,
97    u16: CastInto<F::Int>,
98    i32: CastInto<F::Int>,
99    u32: CastInto<F::Int>,
100    u128: CastInto<HalfRep<F>>,
101{
102    let one = F::Int::ONE;
103    let zero = F::Int::ZERO;
104    let one_hw = HalfRep::<F>::ONE;
105    let zero_hw = HalfRep::<F>::ZERO;
106    let hw = F::BITS / 2;
107    let lo_mask = F::Int::MAX >> hw;
108
109    let significand_bits = F::SIG_BITS;
110    // Saturated exponent, representing infinity
111    let exponent_sat: F::Int = F::EXP_SAT.cast();
112
113    let exponent_bias = F::EXP_BIAS;
114    let implicit_bit = F::IMPLICIT_BIT;
115    let significand_mask = F::SIG_MASK;
116    let sign_bit = F::SIGN_MASK;
117    let abs_mask = sign_bit - one;
118    let exponent_mask = F::EXP_MASK;
119    let inf_rep = exponent_mask;
120    let quiet_bit = implicit_bit >> 1;
121    let qnan_rep = exponent_mask | quiet_bit;
122    let (mut half_iterations, full_iterations) = get_iterations::<F>();
123    let recip_precision = reciprocal_precision::<F>();
124
125    if F::BITS == 128 {
126        // FIXME(tgross35): f128 seems to require one more half iteration than expected
127        half_iterations += 1;
128    }
129
130    let a_rep = a.to_bits();
131    let b_rep = b.to_bits();
132
133    // Exponent numeric representationm not accounting for bias
134    let a_exponent = (a_rep >> significand_bits) & exponent_sat;
135    let b_exponent = (b_rep >> significand_bits) & exponent_sat;
136    let quotient_sign = (a_rep ^ b_rep) & sign_bit;
137
138    let mut a_significand = a_rep & significand_mask;
139    let mut b_significand = b_rep & significand_mask;
140
141    // The exponent of our final result in its encoded form
142    let mut res_exponent: i32 =
143        i32::cast_from(a_exponent) - i32::cast_from(b_exponent) + (exponent_bias as i32);
144
145    // Detect if a or b is zero, denormal, infinity, or NaN.
146    if a_exponent.wrapping_sub(one) >= (exponent_sat - one)
147        || b_exponent.wrapping_sub(one) >= (exponent_sat - one)
148    {
149        let a_abs = a_rep & abs_mask;
150        let b_abs = b_rep & abs_mask;
151
152        // NaN / anything = qNaN
153        if a_abs > inf_rep {
154            return F::from_bits(a_rep | quiet_bit);
155        }
156
157        // anything / NaN = qNaN
158        if b_abs > inf_rep {
159            return F::from_bits(b_rep | quiet_bit);
160        }
161
162        if a_abs == inf_rep {
163            if b_abs == inf_rep {
164                // infinity / infinity = NaN
165                return F::from_bits(qnan_rep);
166            } else {
167                // infinity / anything else = +/- infinity
168                return F::from_bits(a_abs | quotient_sign);
169            }
170        }
171
172        // anything else / infinity = +/- 0
173        if b_abs == inf_rep {
174            return F::from_bits(quotient_sign);
175        }
176
177        if a_abs == zero {
178            if b_abs == zero {
179                // zero / zero = NaN
180                return F::from_bits(qnan_rep);
181            } else {
182                // zero / anything else = +/- zero
183                return F::from_bits(quotient_sign);
184            }
185        }
186
187        // anything else / zero = +/- infinity
188        if b_abs == zero {
189            return F::from_bits(inf_rep | quotient_sign);
190        }
191
192        // a is denormal. Renormalize it and set the scale to include the necessary exponent
193        // adjustment.
194        if a_abs < implicit_bit {
195            let (exponent, significand) = F::normalize(a_significand);
196            res_exponent += exponent;
197            a_significand = significand;
198        }
199
200        // b is denormal. Renormalize it and set the scale to include the necessary exponent
201        // adjustment.
202        if b_abs < implicit_bit {
203            let (exponent, significand) = F::normalize(b_significand);
204            res_exponent -= exponent;
205            b_significand = significand;
206        }
207    }
208
209    // Set the implicit significand bit. If we fell through from the
210    // denormal path it was already set by normalize( ), but setting it twice
211    // won't hurt anything.
212    a_significand |= implicit_bit;
213    b_significand |= implicit_bit;
214
215    // Transform to a fixed-point representation by shifting the significand to the high bits. We
216    // know this is in the range [1.0, 2.0] since the implicit bit is set to 1 above.
217    let b_uq1 = b_significand << (F::BITS - significand_bits - 1);
218
219    // Align the significand of b as a UQ1.(n-1) fixed-point number in the range
220    // [1.0, 2.0) and get a UQ0.n approximate reciprocal using a small minimax
221    // polynomial approximation: x0 = 3/4 + 1/sqrt(2) - b/2.
222    // The max error for this approximation is achieved at endpoints, so
223    //   abs(x0(b) - 1/b) <= abs(x0(1) - 1/1) = 3/4 - 1/sqrt(2) = 0.04289...,
224    // which is about 4.5 bits.
225    // The initial approximation is between x0(1.0) = 0.9571... and x0(2.0) = 0.4571...
226    //
227    // Then, refine the reciprocal estimate using a quadratically converging
228    // Newton-Raphson iteration:
229    //     x_{n+1} = x_n * (2 - x_n * b)
230    //
231    // Let b be the original divisor considered "in infinite precision" and
232    // obtained from IEEE754 representation of function argument (with the
233    // implicit bit set). Corresponds to rep_t-sized b_UQ1 represented in
234    // UQ1.(W-1).
235    //
236    // Let b_hw be an infinitely precise number obtained from the highest (HW-1)
237    // bits of divisor significand (with the implicit bit set). Corresponds to
238    // half_rep_t-sized b_UQ1_hw represented in UQ1.(HW-1) that is a **truncated**
239    // version of b_UQ1.
240    //
241    // Let e_n := x_n - 1/b_hw
242    //     E_n := x_n - 1/b
243    // abs(E_n) <= abs(e_n) + (1/b_hw - 1/b)
244    //           = abs(e_n) + (b - b_hw) / (b*b_hw)
245    //          <= abs(e_n) + 2 * 2^-HW
246    //
247    // rep_t-sized iterations may be slower than the corresponding half-width
248    // variant depending on the handware and whether single/double/quad precision
249    // is selected.
250    //
251    // NB: Using half-width iterations increases computation errors due to
252    // rounding, so error estimations have to be computed taking the selected
253    // mode into account!
254    let mut x_uq0 = if half_iterations > 0 {
255        // Starting with (n-1) half-width iterations
256        let b_uq1_hw: HalfRep<F> = b_uq1.hi();
257
258        // C is (3/4 + 1/sqrt(2)) - 1 truncated to W0 fractional bits as UQ0.HW
259        // with W0 being either 16 or 32 and W0 <= HW.
260        // That is, C is the aforementioned 3/4 + 1/sqrt(2) constant (from which
261        // b/2 is subtracted to obtain x0) wrapped to [0, 1) range.
262        let c_hw = c_hw::<F>();
263
264        // Check that the top bit is set, i.e. value is within `[1, 2)`.
265        debug_assert!(b_uq1_hw & (one_hw << (HalfRep::<F>::BITS - 1)) > zero_hw);
266
267        // b >= 1, thus an upper bound for 3/4 + 1/sqrt(2) - b/2 is about 0.9572,
268        // so x0 fits to UQ0.HW without wrapping.
269        let mut x_uq0_hw: HalfRep<F> =
270            c_hw.wrapping_sub(b_uq1_hw /* exact b_hw/2 as UQ0.HW */);
271
272        // An e_0 error is comprised of errors due to
273        // * x0 being an inherently imprecise first approximation of 1/b_hw
274        // * C_hw being some (irrational) number **truncated** to W0 bits
275        // Please note that e_0 is calculated against the infinitely precise
276        // reciprocal of b_hw (that is, **truncated** version of b).
277        //
278        // e_0 <= 3/4 - 1/sqrt(2) + 2^-W0
279        //
280        // By construction, 1 <= b < 2
281        // f(x)  = x * (2 - b*x) = 2*x - b*x^2
282        // f'(x) = 2 * (1 - b*x)
283        //
284        // On the [0, 1] interval, f(0)   = 0,
285        // then it increses until  f(1/b) = 1 / b, maximum on (0, 1),
286        // then it decreses to     f(1)   = 2 - b
287        //
288        // Let g(x) = x - f(x) = b*x^2 - x.
289        // On (0, 1/b), g(x) < 0 <=> f(x) > x
290        // On (1/b, 1], g(x) > 0 <=> f(x) < x
291        //
292        // For half-width iterations, b_hw is used instead of b.
293        for _ in 0..half_iterations {
294            // corr_UQ1_hw can be **larger** than 2 - b_hw*x by at most 1*Ulp
295            // of corr_UQ1_hw.
296            // "0.0 - (...)" is equivalent to "2.0 - (...)" in UQ1.(HW-1).
297            // On the other hand, corr_UQ1_hw should not overflow from 2.0 to 0.0 provided
298            // no overflow occurred earlier: ((rep_t)x_UQ0_hw * b_UQ1_hw >> HW) is
299            // expected to be strictly positive because b_UQ1_hw has its highest bit set
300            // and x_UQ0_hw should be rather large (it converges to 1/2 < 1/b_hw <= 1).
301            //
302            // Now, we should multiply UQ0.HW and UQ1.(HW-1) numbers, naturally
303            // obtaining an UQ1.(HW-1) number and proving its highest bit could be
304            // considered to be 0 to be able to represent it in UQ0.HW.
305            // From the above analysis of f(x), if corr_UQ1_hw would be represented
306            // without any intermediate loss of precision (that is, in twice_rep_t)
307            // x_UQ0_hw could be at most [1.]000... if b_hw is exactly 1.0 and strictly
308            // less otherwise. On the other hand, to obtain [1.]000..., one have to pass
309            // 1/b_hw == 1.0 to f(x), so this cannot occur at all without overflow (due
310            // to 1.0 being not representable as UQ0.HW).
311            // The fact corr_UQ1_hw was virtually round up (due to result of
312            // multiplication being **first** truncated, then negated - to improve
313            // error estimations) can increase x_UQ0_hw by up to 2*Ulp of x_UQ0_hw.
314            //
315            // Now, either no overflow occurred or x_UQ0_hw is 0 or 1 in its half_rep_t
316            // representation. In the latter case, x_UQ0_hw will be either 0 or 1 after
317            // any number of iterations, so just subtract 2 from the reciprocal
318            // approximation after last iteration.
319            //
320            // In infinite precision, with 0 <= eps1, eps2 <= U = 2^-HW:
321            // corr_UQ1_hw = 2 - (1/b_hw + e_n) * b_hw + 2*eps1
322            //             = 1 - e_n * b_hw + 2*eps1
323            // x_UQ0_hw = (1/b_hw + e_n) * (1 - e_n*b_hw + 2*eps1) - eps2
324            //          = 1/b_hw - e_n + 2*eps1/b_hw + e_n - e_n^2*b_hw + 2*e_n*eps1 - eps2
325            //          = 1/b_hw + 2*eps1/b_hw - e_n^2*b_hw + 2*e_n*eps1 - eps2
326            // e_{n+1} = -e_n^2*b_hw + 2*eps1/b_hw + 2*e_n*eps1 - eps2
327            //         = 2*e_n*eps1 - (e_n^2*b_hw + eps2) + 2*eps1/b_hw
328            //                        \------ >0 -------/   \-- >0 ---/
329            // abs(e_{n+1}) <= 2*abs(e_n)*U + max(2*e_n^2 + U, 2 * U)
330            x_uq0_hw = next_guess(x_uq0_hw, b_uq1_hw);
331        }
332
333        // For initial half-width iterations, U = 2^-HW
334        // Let  abs(e_n)     <= u_n * U,
335        // then abs(e_{n+1}) <= 2 * u_n * U^2 + max(2 * u_n^2 * U^2 + U, 2 * U)
336        // u_{n+1} <= 2 * u_n * U + max(2 * u_n^2 * U + 1, 2)
337        //
338        // Account for possible overflow (see above). For an overflow to occur for the
339        // first time, for "ideal" corr_UQ1_hw (that is, without intermediate
340        // truncation), the result of x_UQ0_hw * corr_UQ1_hw should be either maximum
341        // value representable in UQ0.HW or less by 1. This means that 1/b_hw have to
342        // be not below that value (see g(x) above), so it is safe to decrement just
343        // once after the final iteration. On the other hand, an effective value of
344        // divisor changes after this point (from b_hw to b), so adjust here.
345        x_uq0_hw = x_uq0_hw.wrapping_sub(one_hw);
346
347        // Error estimations for full-precision iterations are calculated just
348        // as above, but with U := 2^-W and taking extra decrementing into account.
349        // We need at least one such iteration.
350        //
351        // Simulating operations on a twice_rep_t to perform a single final full-width
352        // iteration. Using ad-hoc multiplication implementations to take advantage
353        // of particular structure of operands.
354        let blo: F::Int = b_uq1 & lo_mask;
355
356        // x_UQ0 = x_UQ0_hw * 2^HW - 1
357        // x_UQ0 * b_UQ1 = (x_UQ0_hw * 2^HW) * (b_UQ1_hw * 2^HW + blo) - b_UQ1
358        //
359        //   <--- higher half ---><--- lower half --->
360        //   [x_UQ0_hw * b_UQ1_hw]
361        // +            [  x_UQ0_hw *  blo  ]
362        // -                      [      b_UQ1       ]
363        // = [      result       ][.... discarded ...]
364        let corr_uq1: F::Int = (F::Int::from(x_uq0_hw) * F::Int::from(b_uq1_hw)
365            + ((F::Int::from(x_uq0_hw) * blo) >> hw))
366            .wrapping_sub(one)
367            .wrapping_neg(); // account for *possible* carry
368
369        let lo_corr: F::Int = corr_uq1 & lo_mask;
370        let hi_corr: F::Int = corr_uq1 >> hw;
371
372        // x_UQ0 * corr_UQ1 = (x_UQ0_hw * 2^HW) * (hi_corr * 2^HW + lo_corr) - corr_UQ1
373        let mut x_uq0: F::Int = ((F::Int::from(x_uq0_hw) * hi_corr) << 1)
374            .wrapping_add((F::Int::from(x_uq0_hw) * lo_corr) >> (hw - 1))
375            // 1 to account for the highest bit of corr_UQ1 can be 1
376            // 1 to account for possible carry
377            // Just like the case of half-width iterations but with possibility
378            // of overflowing by one extra Ulp of x_UQ0.
379            .wrapping_sub(F::Int::from(2u8));
380
381        x_uq0 -= one;
382        // ... and then traditional fixup by 2 should work
383
384        // On error estimation:
385        // abs(E_{N-1}) <=   (u_{N-1} + 2 /* due to conversion e_n -> E_n */) * 2^-HW
386        //                 + (2^-HW + 2^-W))
387        // abs(E_{N-1}) <= (u_{N-1} + 3.01) * 2^-HW
388        //
389        // Then like for the half-width iterations:
390        // With 0 <= eps1, eps2 < 2^-W
391        // E_N  = 4 * E_{N-1} * eps1 - (E_{N-1}^2 * b + 4 * eps2) + 4 * eps1 / b
392        // abs(E_N) <= 2^-W * [ 4 * abs(E_{N-1}) + max(2 * abs(E_{N-1})^2 * 2^W + 4, 8)) ]
393        // abs(E_N) <= 2^-W * [ 4 * (u_{N-1} + 3.01) * 2^-HW + max(4 + 2 * (u_{N-1} + 3.01)^2, 8) ]
394        x_uq0
395    } else {
396        // C is (3/4 + 1/sqrt(2)) - 1 truncated to 64 fractional bits as UQ0.n
397        let c: F::Int = F::Int::from(0x7504F333u32) << (F::BITS - 32);
398        let mut x_uq0: F::Int = c.wrapping_sub(b_uq1);
399
400        // E_0 <= 3/4 - 1/sqrt(2) + 2 * 2^-64
401        // x_uq0
402        for _ in 0..full_iterations {
403            x_uq0 = next_guess(x_uq0, b_uq1);
404        }
405
406        x_uq0
407    };
408
409    // Finally, account for possible overflow, as explained above.
410    x_uq0 = x_uq0.wrapping_sub(2.cast());
411
412    // Suppose 1/b - P * 2^-W < x < 1/b + P * 2^-W
413    x_uq0 -= recip_precision.cast();
414
415    // Now 1/b - (2*P) * 2^-W < x < 1/b
416    // FIXME Is x_UQ0 still >= 0.5?
417
418    let mut quotient_uq1: F::Int = x_uq0.widen_mul(a_significand << 1).hi();
419    // Now, a/b - 4*P * 2^-W < q < a/b for q=<quotient_UQ1:dummy> in UQ1.(SB+1+W).
420
421    // quotient_UQ1 is in [0.5, 2.0) as UQ1.(SB+1),
422    // adjust it to be in [1.0, 2.0) as UQ1.SB.
423    let mut residual_lo = if quotient_uq1 < (implicit_bit << 1) {
424        // Highest bit is 0, so just reinterpret quotient_UQ1 as UQ1.SB,
425        // effectively doubling its value as well as its error estimation.
426        let residual_lo = (a_significand << (significand_bits + 1))
427            .wrapping_sub(quotient_uq1.wrapping_mul(b_significand));
428        res_exponent -= 1;
429        a_significand <<= 1;
430        residual_lo
431    } else {
432        // Highest bit is 1 (the UQ1.(SB+1) value is in [1, 2)), convert it
433        // to UQ1.SB by right shifting by 1. Least significant bit is omitted.
434        quotient_uq1 >>= 1;
435        (a_significand << significand_bits).wrapping_sub(quotient_uq1.wrapping_mul(b_significand))
436    };
437
438    // drop mutability
439    let quotient = quotient_uq1;
440
441    // NB: residualLo is calculated above for the normal result case.
442    //     It is re-computed on denormal path that is expected to be not so
443    //     performance-sensitive.
444    //
445    // Now, q cannot be greater than a/b and can differ by at most 8*P * 2^-W + 2^-SB
446    // Each NextAfter() increments the floating point value by at least 2^-SB
447    // (more, if exponent was incremented).
448    // Different cases (<---> is of 2^-SB length, * = a/b that is shown as a midpoint):
449    //   q
450    //   |   | * |   |   |       |       |
451    //       <--->      2^t
452    //   |   |   |   |   |   *   |       |
453    //               q
454    // To require at most one NextAfter(), an error should be less than 1.5 * 2^-SB.
455    //   (8*P) * 2^-W + 2^-SB < 1.5 * 2^-SB
456    //   (8*P) * 2^-W         < 0.5 * 2^-SB
457    //   P < 2^(W-4-SB)
458    // Generally, for at most R NextAfter() to be enough,
459    //   P < (2*R - 1) * 2^(W-4-SB)
460    // For f32 (0+3): 10 < 32 (OK)
461    // For f32 (2+1): 32 < 74 < 32 * 3, so two NextAfter() are required
462    // For f64: 220 < 256 (OK)
463    // For f128: 4096 * 3 < 13922 < 4096 * 5 (three NextAfter() are required)
464    //
465    // If we have overflowed the exponent, return infinity
466    if res_exponent >= i32::cast_from(exponent_sat) {
467        return F::from_bits(inf_rep | quotient_sign);
468    }
469
470    // Now, quotient <= the correctly-rounded result
471    // and may need taking NextAfter() up to 3 times (see error estimates above)
472    // r = a - b * q
473    let mut abs_result = if res_exponent > 0 {
474        let mut ret = quotient & significand_mask;
475        ret |= F::Int::from(res_exponent as u32) << significand_bits;
476        residual_lo <<= 1;
477        ret
478    } else {
479        if ((significand_bits as i32) + res_exponent) < 0 {
480            return F::from_bits(quotient_sign);
481        }
482
483        let ret = quotient.wrapping_shr(u32::cast_from(res_exponent.wrapping_neg()) + 1);
484        residual_lo = a_significand
485            .wrapping_shl(significand_bits.wrapping_add(CastInto::<u32>::cast(res_exponent)))
486            .wrapping_sub(ret.wrapping_mul(b_significand) << 1);
487        ret
488    };
489
490    residual_lo += abs_result & one; // tie to even
491    // conditionally turns the below LT comparison into LTE
492    abs_result += u8::from(residual_lo > b_significand).into();
493
494    if F::BITS == 128 || (F::BITS == 32 && half_iterations > 0) {
495        // Do not round Infinity to NaN
496        abs_result +=
497            u8::from(abs_result < inf_rep && residual_lo > (2 + 1).cast() * b_significand).into();
498    }
499
500    if F::BITS == 128 {
501        abs_result +=
502            u8::from(abs_result < inf_rep && residual_lo > (4 + 1).cast() * b_significand).into();
503    }
504
505    F::from_bits(abs_result | quotient_sign)
506}
507
508/// Calculate the number of iterations required for a float type's precision.
509///
510/// This returns `(h, f)` where `h` is the number of iterations to be done using integers at half
511/// the float's bit width, and `f` is the number of iterations done using integers of the float's
512/// full width. This is further explained in the module documentation.
513///
514/// # Requirements
515///
516/// The initial estimate should have at least 8 bits of precision. If this is not true, results
517/// will be inaccurate.
518const fn get_iterations<F: Float>() -> (usize, usize) {
519    // Precision doubles with each iteration. Assume we start with 8 bits of precision.
520    let total_iterations = F::BITS.ilog2() as usize - 2;
521
522    if 2 * size_of::<F>() <= size_of::<*const ()>() {
523        // If widening multiplication will be efficient (uses word-sized integers), there is no
524        // reason to use half-sized iterations.
525        (0, total_iterations)
526    } else {
527        // Otherwise, do as many iterations as possible at half width.
528        (total_iterations - 1, 1)
529    }
530}
531
532/// `u_n` for different precisions (with N-1 half-width iterations).
533///
534/// W0 is the precision of C
535///   u_0 = (3/4 - 1/sqrt(2) + 2^-W0) * 2^HW
536///
537/// Estimated with bc:
538///
539/// ```text
540///   define half1(un) { return 2.0 * (un + un^2) / 2.0^hw + 1.0; }
541///   define half2(un) { return 2.0 * un / 2.0^hw + 2.0; }
542///   define full1(un) { return 4.0 * (un + 3.01) / 2.0^hw + 2.0 * (un + 3.01)^2 + 4.0; }
543///   define full2(un) { return 4.0 * (un + 3.01) / 2.0^hw + 8.0; }
544///
545///             | f32 (0 + 3) | f32 (2 + 1)  | f64 (3 + 1)  | f128 (4 + 1)
546/// u_0         | < 184224974 | < 2812.1     | < 184224974  | < 791240234244348797
547/// u_1         | < 15804007  | < 242.7      | < 15804007   | < 67877681371350440
548/// u_2         | < 116308    | < 2.81       | < 116308     | < 499533100252317
549/// u_3         | < 7.31      |              | < 7.31       | < 27054456580
550/// u_4         |             |              |              | < 80.4
551/// Final (U_N) | same as u_3 | < 72         | < 218        | < 13920
552/// ````
553///
554/// Add 2 to `U_N` due to final decrement.
555const fn reciprocal_precision<F: Float>() -> u16 {
556    let (half_iterations, full_iterations) = get_iterations::<F>();
557
558    if full_iterations < 1 {
559        panic!("Must have at least one full iteration");
560    }
561
562    // FIXME(tgross35): calculate this programmatically
563    if F::BITS == 32 && half_iterations == 2 && full_iterations == 1 {
564        74u16
565    } else if F::BITS == 32 && half_iterations == 0 && full_iterations == 3 {
566        10
567    } else if F::BITS == 64 && half_iterations == 3 && full_iterations == 1 {
568        220
569    } else if F::BITS == 128 && half_iterations == 4 && full_iterations == 1 {
570        13922
571    } else {
572        panic!("Invalid number of iterations")
573    }
574}
575
576/// The value of `C` adjusted to half width.
577///
578/// C is (3/4 + 1/sqrt(2)) - 1 truncated to W0 fractional bits as UQ0.HW with W0 being either
579/// 16 or 32 and W0 <= HW. That is, C is the aforementioned 3/4 + 1/sqrt(2) constant (from
580/// which b/2 is subtracted to obtain x0) wrapped to [0, 1) range.
581fn c_hw<F: Float>() -> HalfRep<F>
582where
583    F::Int: DInt,
584    u128: CastInto<HalfRep<F>>,
585{
586    const C_U128: u128 = 0x7504f333f9de6108b2fb1366eaa6a542;
587    const { C_U128 >> (u128::BITS - <HalfRep<F>>::BITS) }.cast()
588}
589
590/// Perform one iteration at any width to approach `1/b`, given previous guess `x`. Returns
591/// the next `x` as a UQ0 number.
592///
593/// This is the `x_{n+1} = 2*x_n - b*x_n^2` algorithm, implemented as `x_n * (2 - b*x_n)`. It
594/// uses widening multiplication to calculate the result with necessary precision.
595fn next_guess<I>(x_uq0: I, b_uq1: I) -> I
596where
597    I: Int + HInt,
598    <I as HInt>::D: ops::Shr<u32, Output = <I as HInt>::D>,
599{
600    // `corr = 2 - b*x_n`
601    //
602    // This looks like `0 - b*x_n`. However, this works - in `UQ1`, `0.0 - x = 2.0 - x`.
603    let corr_uq1: I = I::ZERO.wrapping_sub(x_uq0.widen_mul(b_uq1).hi());
604
605    // `x_n * corr = x_n * (2 - b*x_n)`
606    (x_uq0.widen_mul(corr_uq1) >> (I::BITS - 1)).lo()
607}
608
609intrinsics! {
610    #[arm_aeabi_alias = __aeabi_fdiv]
611    pub extern "C" fn __divsf3(a: f32, b: f32) -> f32 {
612        div(a, b)
613    }
614
615    #[arm_aeabi_alias = __aeabi_ddiv]
616    pub extern "C" fn __divdf3(a: f64, b: f64) -> f64 {
617        div(a, b)
618    }
619
620    #[ppc_alias = __divkf3]
621    #[cfg(f128_enabled)]
622    pub extern "C" fn __divtf3(a: f128, b: f128) -> f128 {
623        div(a, b)
624    }
625
626    #[cfg(target_arch = "arm")]
627    pub extern "C" fn __divsf3vfp(a: f32, b: f32) -> f32 {
628        a / b
629    }
630
631    #[cfg(target_arch = "arm")]
632    pub extern "C" fn __divdf3vfp(a: f64, b: f64) -> f64 {
633        a / b
634    }
635}