Skip to main content

a/math/numbers/
div.rs

1//! Division of [`Number`]s: `/` and `/=` for the quotient and `%` and `%=` for the remainder, with
2//! either operand owned or borrowed, and [`Number::div_rem`], [`Number::div_euclid`] and
3//! [`Number::rem_euclid`].
4//!
5//! The rules are those of Rust's primitive integers. The quotient `a / b` is truncated toward
6//! zero, and the remainder `a % b` is what is left, `a - (a / b) b`: it has the sign of `a` and a
7//! magnitude below that of `b`, so `-7 / 2 = -3` and `-7 % 2 = -1`. `div_euclid` and `rem_euclid`
8//! give Euclid's division instead, whose remainder is never negative: `-7 = 2 (-4) + 1`. Dividing by
9//! zero panics, as it does for `i32`. A zero magnitude is zero whatever `negative` says, and zero
10//! bytes above the most significant one count for nothing.
11//!
12//! Operands whose vectors both hold at most 16 bytes take a short path in registers: their
13//! magnitudes are read into `u128`s as the addition reads them and divided, and the result is
14//! written in the byte order of the left operand. A dividend of up to 64 bytes by a divisor of up
15//! to 16 is divided in registers too, by the steps below.
16//!
17//! Longer operands are read into limbs of eight bytes, native `u64`s, the least significant first,
18//! in working memory on the stack, or on the heap for the longest. Both are shifted left by the
19//! same number of bits, so that the divisor's top bit is set: its top limbs then give each limb of
20//! the quotient by a multiplication with their precomputed reciprocal (see [`limbs`]). A divisor of
21//! one limb or two divides limb by limb; a longer one by the schoolbook method, each quotient limb
22//! times the divisor subtracted from the partial remainder by kernels in inline assembly on 64-bit
23//! little-endian `aarch64` and, with BMI2, on `x86_64`, and portable Rust elsewhere and under Miri;
24//! a divisor of 40 limbs or more by divide and conquer, on the multiplication; and the longest
25//! divisions, from 128 limbs in the divisor and 768 in the quotient, the quotient at least an
26//! eighth of the divisor, by Newton's method (see [`newton`]). The remainder is shifted back, and the quotient and the remainder are written as
27//! the operators promise. `/` computes the quotient alone, from the top limbs of the operands when
28//! it is much shorter than the divisor, and `%` by a divisor of one limb the remainder alone.
29//!
30//! A quotient is never longer than the dividend, nor a remainder than the divisor or the dividend,
31//! so the dividend's vector, when it is taken by value or is the target of `/=` or `%=`, has room
32//! for the result, except for zero in an empty vector, and so has the divisor's for a remainder.
33//!
34//! [`Number::div_exact`] and [`Number::is_multiple_of`] are in [`exact`], and a divisor prepared
35//! for many divisions, [`Divisor`](super::Divisor), divides by the same steps.
36
37// The kernel of the schoolbook method under the name `kernels`, chosen as those of the addition
38// are: assembly on 64-bit little-endian aarch64 where the system allows unaligned accesses and on
39// x86_64, and portable Rust elsewhere and under Miri.
40mod exact;
41#[cfg(all(
42    target_arch = "aarch64",
43    target_endian = "little",
44    target_pointer_width = "64",
45    any(
46        target_vendor = "apple",
47        target_os = "linux",
48        target_os = "android",
49        target_os = "windows",
50        target_os = "freebsd",
51        target_os = "netbsd",
52        target_os = "openbsd",
53        target_os = "fuchsia"
54    ),
55    not(miri)
56))]
57#[path = "div/aarch64.rs"]
58mod kernels;
59#[cfg(all(target_arch = "x86_64", not(miri)))]
60#[path = "div/x86_64.rs"]
61mod kernels;
62#[cfg(not(any(
63    all(
64        target_arch = "aarch64",
65        target_endian = "little",
66        target_pointer_width = "64",
67        any(
68            target_vendor = "apple",
69            target_os = "linux",
70            target_os = "android",
71            target_os = "windows",
72            target_os = "freebsd",
73            target_os = "netbsd",
74            target_os = "openbsd",
75            target_os = "fuchsia"
76        ),
77        not(miri)
78    ),
79    all(target_arch = "x86_64", not(miri))
80)))]
81#[path = "div/portable.rs"]
82mod kernels;
83pub(super) mod limbs;
84mod newton;
85mod rem1;
86
87pub(super) use limbs::{div_2by1 as divide_2by1, invert_limb as reciprocal};
88pub(super) use rem1::{
89    Powers, REM_1_BYTES, REM_1_BYTES_WIDE, REM_1_MAX, REM_1_PREPARED, limb_of, rem_1,
90};
91
92use super::add::{SMALL, read, read_small, small, write_small};
93use super::mul::limbs::{add_1, sub_n};
94use super::mul::{
95    Operand, Product, STACK_LIMBS, WIDE, Wide, on_heap, on_stack, put_wide, read_wide,
96};
97use super::sub::Negated;
98use super::{ByteOrder, Number};
99use core::cmp::Ordering::Less;
100use core::mem::{self, MaybeUninit};
101use core::ops::{Div, DivAssign, Rem, RemAssign};
102use core::ptr;
103use limbs::{
104    DC_DIV, DC_DIV_Q, Found, check_itch, check_q_top, div_2by1, div_3by2, div_q, div_q_split,
105    div_q_top, div_qr, div_qr_1, div_qr_2, from_top, invert_3by2, invert_limb, q_itch, qr_itch,
106    rshift, split_itch, split_low, top_itch,
107};
108pub(super) use newton::{Prepared, mu, mu_prepared, prepare};
109use newton::{mu_div_prepared, mu_div_q};
110
111impl Div<&Number> for &Number {
112    type Output = Number;
113
114    /// Returns `self / rhs`, truncated toward zero, in the byte order of `self`, in the shortest
115    /// form.
116    ///
117    /// The quotient is built in one new vector of exactly its length (one byte for zero); both
118    /// operands are left as they were. The operands may have any signs, byte orders and lengths,
119    /// and need not be in the shortest form.
120    ///
121    /// # Panics
122    ///
123    /// When `rhs` is zero.
124    ///
125    /// # Examples
126    ///
127    /// ```
128    /// use a::math::numbers::{ByteOrder, Number};
129    ///
130    /// // -0x01_00 / 3 = -0x55, truncated toward zero, in the byte order of the left operand.
131    /// let a = Number::new_from_i32(-0x0100, ByteOrder::BigEndian);
132    /// let b = Number::new_from_i32(3, ByteOrder::LittleEndian);
133    /// let quotient = &a / &b;
134    /// assert_eq!(quotient.value, [0x55]);
135    /// assert!(quotient.is_negative());
136    /// assert!(quotient.byte_order() == ByteOrder::BigEndian);
137    /// ```
138    #[track_caller]
139    fn div(self, rhs: &Number) -> Number {
140        if small(self, rhs) {
141            let (q, _) = small_division::<TRUNCATED, false>(self, rhs);
142            return small_number(self.byte_order, q);
143        }
144        ref_by_ref::<TRUNCATED, false>(self, rhs)
145    }
146}
147
148impl Div<&Number> for Number {
149    type Output = Number;
150
151    /// Returns `self / rhs`, truncated toward zero, in the byte order of `self`, in the shortest
152    /// form, as `self /= rhs` does.
153    ///
154    /// The quotient is built in the vector of `self`, which has room for it unless `self` is an
155    /// empty vector; `rhs` is left as it was.
156    ///
157    /// # Panics
158    ///
159    /// When `rhs` is zero.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use a::math::numbers::{ByteOrder, Number};
165    ///
166    /// let a = Number::new(vec![0x01, 0x00, 0x00], ByteOrder::BigEndian);
167    /// let pointer = a.value.as_ptr();
168    ///
169    /// // 0x01_00_00 / 0x01_01 = 0xFF, in the vector of `a`.
170    /// let quotient = a / &Number::new_from_u16(0x0101, ByteOrder::LittleEndian);
171    /// assert_eq!(quotient.value, [0xFF]);
172    /// assert_eq!(quotient.value.as_ptr(), pointer);
173    /// ```
174    #[track_caller]
175    fn div(mut self, rhs: &Number) -> Number {
176        self /= rhs;
177        self
178    }
179}
180
181impl Div<Number> for &Number {
182    type Output = Number;
183
184    /// Returns `self / rhs`, truncated toward zero, in the byte order of `self`, in the shortest
185    /// form.
186    ///
187    /// The quotient is built in the vector of `rhs` when its capacity has room for it, also when
188    /// `rhs` is in the other byte order; otherwise it gets one new vector of exactly its length.
189    /// `self` is left as it was.
190    ///
191    /// # Panics
192    ///
193    /// When `rhs` is zero.
194    ///
195    /// # Examples
196    ///
197    /// ```
198    /// use a::math::numbers::{ByteOrder, Number};
199    ///
200    /// let a = Number::new_from_u16(0x0300, ByteOrder::BigEndian);
201    /// let mut value = Vec::with_capacity(2);
202    /// value.push(3);
203    /// let b = Number::new(value, ByteOrder::LittleEndian);
204    /// let pointer = b.value.as_ptr();
205    ///
206    /// // 0x03_00 / 3 = 0x01_00, big-endian, in the vector of `b`.
207    /// let quotient = &a / b;
208    /// assert_eq!(quotient.value, [0x01, 0x00]);
209    /// assert_eq!(quotient.value.as_ptr(), pointer);
210    /// ```
211    #[track_caller]
212    fn div(self, mut rhs: Number) -> Number {
213        if small(self, &rhs) {
214            let (q, _) = small_division::<TRUNCATED, false>(self, &rhs);
215            put_small(&mut rhs.value, self.byte_order, q);
216            return Number {
217                value: rhs.value,
218                negative: q.negative,
219                byte_order: self.byte_order,
220            };
221        }
222        // `rhs` is dropped on return, with the vector it holds then, if any.
223        ref_by_value::<false>(self, &mut rhs)
224    }
225}
226
227impl Div<Number> for Number {
228    type Output = Number;
229
230    /// Returns `self / rhs`, truncated toward zero, in the byte order of `self`, in the shortest
231    /// form, as `self /= rhs` does.
232    ///
233    /// The quotient is built in the vector of `self`, which has room for it unless `self` is an
234    /// empty vector, and then in the vector of `rhs` when that has room.
235    ///
236    /// # Panics
237    ///
238    /// When `rhs` is zero.
239    ///
240    /// # Examples
241    ///
242    /// ```
243    /// use a::math::numbers::{ByteOrder, Number};
244    ///
245    /// // -7 / -2 = 3.
246    /// let a = Number::new_from_i32(-7, ByteOrder::LittleEndian);
247    /// let b = Number::new_from_i32(-2, ByteOrder::BigEndian);
248    /// let quotient = a / b;
249    /// assert_eq!(quotient.value, [3]);
250    /// assert!(!quotient.is_negative());
251    /// ```
252    #[track_caller]
253    fn div(mut self, rhs: Number) -> Number {
254        self /= rhs;
255        self
256    }
257}
258
259impl DivAssign<&Number> for Number {
260    /// Divides `self` by `rhs`, truncating toward zero, keeping the byte order of `self`, in the
261    /// shortest form.
262    ///
263    /// The quotient is built in the vector of `self`, which has room for it unless `self` is an
264    /// empty vector; `rhs` is left as it was.
265    ///
266    /// # Panics
267    ///
268    /// When `rhs` is zero.
269    ///
270    /// # Examples
271    ///
272    /// ```
273    /// use a::math::numbers::{ByteOrder, Number};
274    ///
275    /// let mut n = Number::new_from_u16(0x1000, ByteOrder::LittleEndian);
276    /// n /= &Number::new_from_u8(0x10, ByteOrder::BigEndian);
277    /// assert_eq!(n.value, [0x00, 0x01]);
278    /// n /= &Number::new_from_i8(-3, ByteOrder::BigEndian);
279    /// assert_eq!(n.value, [0x55]);
280    /// assert!(n.is_negative());
281    /// ```
282    #[inline]
283    #[track_caller]
284    fn div_assign(&mut self, rhs: &Number) {
285        if small(self, rhs) {
286            let (q, _) = small_division::<TRUNCATED, false>(self, rhs);
287            put_small(&mut self.value, self.byte_order, q);
288            self.negative = q.negative;
289            return;
290        }
291        assign_ref::<false>(self, rhs);
292    }
293}
294
295impl DivAssign<Number> for Number {
296    /// Divides `self` by `rhs`, truncating toward zero, keeping the byte order of `self`, in the
297    /// shortest form.
298    ///
299    /// The quotient is built in the vector of `self`, which has room for it unless `self` is an
300    /// empty vector, and then in the vector of `rhs` when that has room.
301    ///
302    /// # Panics
303    ///
304    /// When `rhs` is zero.
305    ///
306    /// # Examples
307    ///
308    /// ```
309    /// use a::math::numbers::{ByteOrder, Number};
310    ///
311    /// let mut n = Number::new_from_u32(1_000_000, ByteOrder::BigEndian);
312    /// n /= Number::new_from_u16(1000, ByteOrder::BigEndian);
313    /// assert_eq!(n.value, [0x03, 0xE8]);
314    /// ```
315    #[inline]
316    #[track_caller]
317    fn div_assign(&mut self, mut rhs: Number) {
318        if small(self, &rhs) {
319            let (q, _) = small_division::<TRUNCATED, false>(self, &rhs);
320            if self.value.capacity() < q.len && rhs.value.capacity() >= q.len {
321                // The vector of `self` goes to `rhs`, and is dropped with it.
322                mem::swap(&mut self.value, &mut rhs.value);
323            }
324            put_small(&mut self.value, self.byte_order, q);
325            self.negative = q.negative;
326            return;
327        }
328        // `rhs` is dropped on return, with the vector it holds then.
329        assign_value::<false>(self, &mut rhs);
330    }
331}
332
333impl Rem<&Number> for &Number {
334    type Output = Number;
335
336    /// Returns `self % rhs`, the remainder of the division truncated toward zero, in the byte
337    /// order of `self`, in the shortest form: it has the sign of `self`, unless it is zero, and a
338    /// magnitude below that of `rhs`.
339    ///
340    /// The remainder is built in one new vector of exactly its length (one byte for zero); both
341    /// operands are left as they were.
342    ///
343    /// # Panics
344    ///
345    /// When `rhs` is zero.
346    ///
347    /// # Examples
348    ///
349    /// ```
350    /// use a::math::numbers::{ByteOrder, Number};
351    ///
352    /// // -7 % 2 = -1 and 7 % -2 = 1, as for `i32`.
353    /// let two = Number::new_from_i32(2, ByteOrder::BigEndian);
354    /// let remainder = &Number::new_from_i32(-7, ByteOrder::BigEndian) % &two;
355    /// assert_eq!(remainder.value, [1]);
356    /// assert!(remainder.is_negative());
357    ///
358    /// let minus_two = Number::new_from_i32(-2, ByteOrder::BigEndian);
359    /// let remainder = &Number::new_from_i32(7, ByteOrder::BigEndian) % &minus_two;
360    /// assert_eq!(remainder.value, [1]);
361    /// assert!(!remainder.is_negative());
362    /// ```
363    #[track_caller]
364    fn rem(self, rhs: &Number) -> Number {
365        if small(self, rhs) {
366            let (_, r) = small_division::<TRUNCATED, true>(self, rhs);
367            return small_number(self.byte_order, r);
368        }
369        ref_by_ref::<TRUNCATED, true>(self, rhs)
370    }
371}
372
373impl Rem<&Number> for Number {
374    type Output = Number;
375
376    /// Returns `self % rhs` as `&self % rhs` does, as `self %= rhs` does.
377    ///
378    /// The remainder is built in the vector of `self`, which has room for it unless `self` is an
379    /// empty vector; `rhs` is left as it was.
380    ///
381    /// # Panics
382    ///
383    /// When `rhs` is zero.
384    ///
385    /// # Examples
386    ///
387    /// ```
388    /// use a::math::numbers::{ByteOrder, Number};
389    ///
390    /// let a = Number::new_from_u32(1_000_003, ByteOrder::LittleEndian);
391    /// let pointer = a.value.as_ptr();
392    /// let remainder = a % &Number::new_from_u16(1000, ByteOrder::BigEndian);
393    /// assert_eq!(remainder.value, [3]);
394    /// assert_eq!(remainder.value.as_ptr(), pointer);
395    /// ```
396    #[track_caller]
397    fn rem(mut self, rhs: &Number) -> Number {
398        self %= rhs;
399        self
400    }
401}
402
403impl Rem<Number> for &Number {
404    type Output = Number;
405
406    /// Returns `self % rhs` as `&self % &rhs` does.
407    ///
408    /// The remainder is built in the vector of `rhs`, which always has room for it, as it is
409    /// shorter than `rhs`, also when `rhs` is in the other byte order. `self` is left as it was.
410    ///
411    /// # Panics
412    ///
413    /// When `rhs` is zero.
414    ///
415    /// # Examples
416    ///
417    /// ```
418    /// use a::math::numbers::{ByteOrder, Number};
419    ///
420    /// let a = Number::new_from_u32(0x01_02_03, ByteOrder::BigEndian);
421    /// let b = Number::new_from_u16(0x0100, ByteOrder::LittleEndian);
422    /// let pointer = b.value.as_ptr();
423    ///
424    /// // 0x01_02_03 % 0x01_00 = 3, big-endian, in the vector of `b`.
425    /// let remainder = &a % b;
426    /// assert_eq!(remainder.value, [3]);
427    /// assert_eq!(remainder.value.as_ptr(), pointer);
428    /// ```
429    #[track_caller]
430    fn rem(self, mut rhs: Number) -> Number {
431        if small(self, &rhs) {
432            let (_, r) = small_division::<TRUNCATED, true>(self, &rhs);
433            put_small(&mut rhs.value, self.byte_order, r);
434            return Number {
435                value: rhs.value,
436                negative: r.negative,
437                byte_order: self.byte_order,
438            };
439        }
440        ref_by_value::<true>(self, &mut rhs)
441    }
442}
443
444impl Rem<Number> for Number {
445    type Output = Number;
446
447    /// Returns `self % rhs` as `&self % &rhs` does, as `self %= rhs` does.
448    ///
449    /// The remainder is built in the vector of `self`, which has room for it unless `self` is an
450    /// empty vector, and then in the vector of `rhs`.
451    ///
452    /// # Panics
453    ///
454    /// When `rhs` is zero.
455    ///
456    /// # Examples
457    ///
458    /// ```
459    /// use a::math::numbers::{ByteOrder, Number};
460    ///
461    /// let a = Number::new_from_i32(-1000, ByteOrder::BigEndian);
462    /// let b = Number::new_from_i32(7, ByteOrder::BigEndian);
463    /// let remainder = a % b;
464    /// // -1000 = 7 (-142) - 6.
465    /// assert_eq!(remainder.value, [6]);
466    /// assert!(remainder.is_negative());
467    /// ```
468    #[track_caller]
469    fn rem(mut self, rhs: Number) -> Number {
470        self %= rhs;
471        self
472    }
473}
474
475impl RemAssign<&Number> for Number {
476    /// Sets `self` to `self % rhs`, keeping the byte order of `self`, in the shortest form.
477    ///
478    /// The remainder is built in the vector of `self`, which has room for it unless `self` is an
479    /// empty vector; `rhs` is left as it was.
480    ///
481    /// # Panics
482    ///
483    /// When `rhs` is zero.
484    ///
485    /// # Examples
486    ///
487    /// ```
488    /// use a::math::numbers::{ByteOrder, Number};
489    ///
490    /// let mut n = Number::new_from_u32(0x0102_0304, ByteOrder::LittleEndian);
491    /// n %= &Number::new_from_u32(0x0001_0000, ByteOrder::BigEndian);
492    /// assert_eq!(n.value, [0x04, 0x03]);
493    /// ```
494    #[inline]
495    #[track_caller]
496    fn rem_assign(&mut self, rhs: &Number) {
497        if small(self, rhs) {
498            let (_, r) = small_division::<TRUNCATED, true>(self, rhs);
499            put_small(&mut self.value, self.byte_order, r);
500            self.negative = r.negative;
501            return;
502        }
503        assign_ref::<true>(self, rhs);
504    }
505}
506
507impl RemAssign<Number> for Number {
508    /// Sets `self` to `self % rhs`, keeping the byte order of `self`, in the shortest form.
509    ///
510    /// The remainder is built in the vector of `self`, which has room for it unless `self` is an
511    /// empty vector, and then in the vector of `rhs`.
512    ///
513    /// # Panics
514    ///
515    /// When `rhs` is zero.
516    ///
517    /// # Examples
518    ///
519    /// ```
520    /// use a::math::numbers::{ByteOrder, Number};
521    ///
522    /// let mut n = Number::new_from_i32(-0x0105, ByteOrder::BigEndian);
523    /// n %= Number::new_from_i32(-0x0100, ByteOrder::BigEndian);
524    /// assert_eq!(n.value, [5]);
525    /// assert!(n.is_negative());
526    /// ```
527    #[inline]
528    #[track_caller]
529    fn rem_assign(&mut self, mut rhs: Number) {
530        if small(self, &rhs) {
531            let (_, r) = small_division::<TRUNCATED, true>(self, &rhs);
532            if self.value.capacity() < r.len {
533                mem::swap(&mut self.value, &mut rhs.value);
534            }
535            put_small(&mut self.value, self.byte_order, r);
536            self.negative = r.negative;
537            return;
538        }
539        assign_value::<true>(self, &mut rhs);
540    }
541}
542
543impl Number {
544    /// Returns the quotient and the remainder of `self` divided by `rhs`, `(self / rhs, self %
545    /// rhs)`, computed together: the quotient truncated toward zero, the remainder with the sign of
546    /// `self`, both in the byte order of `self` and in the shortest form.
547    ///
548    /// Each is built in one new vector of exactly its length (one byte for zero); both operands
549    /// are left as they were.
550    ///
551    /// # Panics
552    ///
553    /// When `rhs` is zero.
554    ///
555    /// # Examples
556    ///
557    /// ```
558    /// use a::math::numbers::{ByteOrder, Number};
559    ///
560    /// // -1000 = 7 (-142) - 6.
561    /// let a = Number::new_from_i32(-1000, ByteOrder::BigEndian);
562    /// let (q, r) = a.div_rem(&Number::new_from_i32(7, ByteOrder::BigEndian));
563    /// assert_eq!(q.value, [142]);
564    /// assert!(q.is_negative());
565    /// assert_eq!(r.value, [6]);
566    /// assert!(r.is_negative());
567    /// ```
568    #[track_caller]
569    pub fn div_rem(&self, rhs: &Number) -> (Number, Number) {
570        if small(self, rhs) {
571            let (q, r) = small_division::<TRUNCATED, false>(self, rhs);
572            return (
573                small_number(self.byte_order, q),
574                small_number(self.byte_order, r),
575            );
576        }
577        both::<TRUNCATED>(self, rhs)
578    }
579
580    /// Returns the quotient of Euclid's division of `self` by `rhs`: the `q` for which `self = rhs
581    /// q + r` with `0 <= r < |rhs|`, in the byte order of `self` and in the shortest form, as
582    /// `i32::div_euclid` gives it.
583    ///
584    /// It is `self / rhs` unless the remainder `self % rhs` is below zero, and then one further
585    /// from zero: `-7 / 2 = -3`, but the Euclidean quotient is `-4`. It is built in one new vector
586    /// of exactly its length.
587    ///
588    /// # Panics
589    ///
590    /// When `rhs` is zero.
591    ///
592    /// # Examples
593    ///
594    /// ```
595    /// use a::math::numbers::{ByteOrder, Number};
596    ///
597    /// let a = Number::new_from_i32(-7, ByteOrder::BigEndian);
598    /// let q = a.div_euclid(&Number::new_from_i32(2, ByteOrder::BigEndian));
599    /// assert_eq!(q.value, [4]);
600    /// assert!(q.is_negative());
601    ///
602    /// let q = a.div_euclid(&Number::new_from_i32(-2, ByteOrder::BigEndian));
603    /// assert_eq!(q.value, [4]);
604    /// assert!(!q.is_negative());
605    /// ```
606    #[track_caller]
607    pub fn div_euclid(&self, rhs: &Number) -> Number {
608        if small(self, rhs) {
609            let (q, _) = small_division::<EUCLID, false>(self, rhs);
610            return small_number(self.byte_order, q);
611        }
612        ref_by_ref::<EUCLID, false>(self, rhs)
613    }
614
615    /// Returns the remainder of Euclid's division of `self` by `rhs`, `self` modulo `|rhs|`: the
616    /// `r` for which `self = rhs q + r` with `0 <= r < |rhs|`, in the byte order of `self` and in
617    /// the shortest form, as `i32::rem_euclid` gives it. It is never negative.
618    ///
619    /// It is `self % rhs` when that is not below zero, and `self % rhs + |rhs|` otherwise. It is
620    /// built in one new vector of exactly its length.
621    ///
622    /// # Panics
623    ///
624    /// When `rhs` is zero.
625    ///
626    /// # Examples
627    ///
628    /// ```
629    /// use a::math::numbers::{ByteOrder, Number};
630    ///
631    /// let a = Number::new_from_i32(-7, ByteOrder::BigEndian);
632    /// let r = a.rem_euclid(&Number::new_from_i32(2, ByteOrder::BigEndian));
633    /// assert_eq!(r.value, [1]);
634    /// assert!(!r.is_negative());
635    ///
636    /// let r = a.rem_euclid(&Number::new_from_i32(-2, ByteOrder::BigEndian));
637    /// assert_eq!(r.value, [1]);
638    /// assert!(!r.is_negative());
639    /// ```
640    #[track_caller]
641    pub fn rem_euclid(&self, rhs: &Number) -> Number {
642        if small(self, rhs) {
643            let (_, r) = small_division::<EUCLID, true>(self, rhs);
644            return small_number(self.byte_order, r);
645        }
646        ref_by_ref::<EUCLID, true>(self, rhs)
647    }
648}
649
650impl Number {
651    /// Returns the quotient of `self` divided by `rhs` rounded toward negative infinity, `⌊self /
652    /// rhs⌋`, in the byte order of `self` and in the shortest form, as Python's `//` and GMP's
653    /// `mpz_fdiv_q` give it.
654    ///
655    /// It is `self / rhs` unless the remainder `self % rhs` is not zero and the operands have
656    /// different signs, and then one less: `-7 / 2 = -3`, but `⌊-7 / 2⌋ = -4`. For a positive
657    /// `rhs` it is [`div_euclid`](Self::div_euclid); for a negative one, `-((-self).div_euclid(rhs))`,
658    /// which is how it is computed, with `-self` a view of `self` with the other sign, so that it
659    /// costs what `div_euclid` does.
660    ///
661    /// # Panics
662    ///
663    /// When `rhs` is zero.
664    ///
665    /// # Examples
666    ///
667    /// ```
668    /// use a::math::numbers::{ByteOrder, Number};
669    ///
670    /// let a = Number::new_from_i32(-7, ByteOrder::BigEndian);
671    /// assert_eq!(a.div_floor(&Number::from(2)), -4);
672    /// assert_eq!(a.div_floor(&Number::from(-2)), 3);
673    /// assert_eq!(Number::from(7).div_floor(&Number::from(-2)), -4);
674    /// ```
675    #[track_caller]
676    pub fn div_floor(&self, rhs: &Number) -> Number {
677        if rhs.is_negative() {
678            -Negated::new(self).div_euclid(rhs)
679        } else {
680            self.div_euclid(rhs)
681        }
682    }
683
684    /// Returns the remainder of `self` divided by `rhs` rounded toward negative infinity, `self -
685    /// rhs·⌊self / rhs⌋`, in the byte order of `self` and in the shortest form, as Python's `%`
686    /// and GMP's `mpz_fdiv_r` give it: it has the sign of `rhs`, unless it is zero, and a magnitude
687    /// below that of `rhs`.
688    ///
689    /// For a positive `rhs` it is [`rem_euclid`](Self::rem_euclid); for a negative one,
690    /// `-((-self).rem_euclid(rhs))`, computed as [`div_floor`](Self::div_floor) is.
691    ///
692    /// # Panics
693    ///
694    /// When `rhs` is zero.
695    ///
696    /// # Examples
697    ///
698    /// ```
699    /// use a::math::numbers::{ByteOrder, Number};
700    ///
701    /// let a = Number::new_from_i32(-7, ByteOrder::BigEndian);
702    /// assert_eq!(a.rem_floor(&Number::from(2)), 1);
703    /// assert_eq!(a.rem_floor(&Number::from(-2)), -1);
704    /// assert_eq!(Number::from(7).rem_floor(&Number::from(-2)), -1);
705    /// ```
706    #[track_caller]
707    pub fn rem_floor(&self, rhs: &Number) -> Number {
708        if rhs.is_negative() {
709            -Negated::new(self).rem_euclid(rhs)
710        } else {
711            self.rem_euclid(rhs)
712        }
713    }
714}
715
716/// The division whose quotient is truncated toward zero, and whose remainder has the sign of the
717/// dividend: `/`, `%` and `div_rem`.
718pub(super) const TRUNCATED: bool = false;
719
720/// Euclid's division, whose remainder is never negative: `div_euclid` and `rem_euclid`.
721pub(super) const EUCLID: bool = true;
722
723/// Panics for a division by zero, with the message of the primitive integers: of `%` when
724/// `REM`, of `/` otherwise.
725#[cold]
726#[inline(never)]
727#[track_caller]
728pub(super) fn by_zero<const REM: bool>() -> ! {
729    if REM {
730        panic!("attempt to calculate the remainder with a divisor of zero")
731    } else {
732        panic!("attempt to divide by zero")
733    }
734}
735
736// Small numbers
737
738/// A quotient or a remainder of two small operands, as the small path computes it in registers.
739#[derive(Clone, Copy)]
740struct Small {
741    /// The low eight bytes of the magnitude.
742    lo: u64,
743    /// The next eight bytes of the magnitude.
744    hi: u64,
745    /// The length in the shortest form, from 1 to 16: one byte for zero.
746    len: usize,
747    /// Whether it is negative; never for zero.
748    negative: bool,
749}
750
751impl Small {
752    /// The magnitude `m` with the sign `negative`, which zero does not keep.
753    #[inline(always)]
754    fn of(m: u128, negative: bool) -> Small {
755        Small {
756            lo: m as u64,
757            hi: (m >> 64) as u64,
758            len: 16 - (m | 1).leading_zeros() as usize / 8,
759            negative: negative && m != 0,
760        }
761    }
762}
763
764/// The quotient and the remainder of the small operands `a` and `b`: truncated, or Euclid's with
765/// `EUCLIDEAN`. Panics with the message of `%` when `REM`, of `/` otherwise, when `b` is zero.
766#[inline(always)]
767#[track_caller]
768fn small_division<const EUCLIDEAN: bool, const REM: bool>(
769    a: &Number,
770    b: &Number,
771) -> (Small, Small) {
772    // SAFETY: both vectors hold at most 16 bytes, as `small` checked.
773    let (x, y) = unsafe {
774        (
775            read_small(&a.value, a.byte_order),
776            read_small(&b.value, b.byte_order),
777        )
778    };
779    if y == 0 {
780        by_zero::<REM>();
781    }
782    let (q, r) = div_u128(x, y);
783    let negative_a = a.negative && x != 0;
784    if EUCLIDEAN && negative_a && r != 0 {
785        // One further from zero, which leaves the remainder `y - r`: with `r != 0`, `y >= 2`, and
786        // `q <= x / 2` does not overflow.
787        return (
788            Small::of(q + 1, a.negative != b.negative),
789            Small::of(y - r, false),
790        );
791    }
792    (
793        Small::of(q, a.negative != b.negative),
794        Small::of(r, negative_a && !EUCLIDEAN),
795    )
796}
797
798/// The quotient and the remainder of `x` by `y > 0`: by the hardware's division when both fit in
799/// a limb; by a divisor of one limb, normalized, its reciprocal computed and the two limbs of `x`
800/// divided by [`div_2by1`] steps, when only `y` does, which took 30 cycles instead of the 56 of the
801/// `u128` division of the compiler's runtime on an Apple M4 Max; and by that division otherwise,
802/// whose quotient is then a single limb.
803#[inline(always)]
804fn div_u128(x: u128, y: u128) -> (u128, u128) {
805    if y >> 64 == 0 {
806        let y = y as u64;
807        if x >> 64 == 0 {
808            let x = x as u64;
809            return (u128::from(x / y), u128::from(x % y));
810        }
811        let s = y.leading_zeros();
812        let (d, u) = (y << s, x << s);
813        let v = invert_limb(d);
814        // The bits shifted out of the top, below `2^s`, are below `d`.
815        let top = ((x >> 64) as u64 >> 1) >> (63 - s);
816        let (q1, t) = div_2by1(top, (u >> 64) as u64, d, v);
817        let (q0, r) = div_2by1(t, u as u64, d, v);
818        return ((u128::from(q1) << 64) | u128::from(q0), u128::from(r >> s));
819    }
820    (x / y, x % y)
821}
822
823/// Writes the small result `s` as the whole value of `v`, in its vector when it has room, in a new
824/// one otherwise.
825#[inline(always)]
826fn put_small(v: &mut Vec<u8>, order: ByteOrder, s: Small) {
827    if v.capacity() >= s.len {
828        // SAFETY: the vector has room for the `s.len` bytes, all of which are written before the
829        // length is set.
830        unsafe {
831            write_small(v.as_mut_ptr(), order, s.lo, s.hi, s.len);
832            v.set_len(s.len);
833        }
834    } else {
835        replace_small(v, order, s);
836    }
837}
838
839/// Replaces `v` with one new vector of exactly the small result's length, holding it. Out of line
840/// and cold, so that the small path saves no registers for it.
841#[cold]
842#[inline(never)]
843fn replace_small(v: &mut Vec<u8>, order: ByteOrder, s: Small) {
844    *v = new_small(order, s);
845}
846
847/// The small result `s` in one new vector of exactly its length.
848#[inline(always)]
849fn new_small(order: ByteOrder, s: Small) -> Vec<u8> {
850    let mut v = Vec::with_capacity(s.len);
851    // SAFETY: the new vector has room for the `s.len` bytes, all of which are written before the
852    // length is set.
853    unsafe {
854        write_small(v.as_mut_ptr(), order, s.lo, s.hi, s.len);
855        v.set_len(s.len);
856    }
857    v
858}
859
860/// The small result `s` as a number in one new vector, in the byte order `order`. Out of line, so
861/// that the small path saves no registers for the allocation.
862#[inline(never)]
863fn small_number(order: ByteOrder, s: Small) -> Number {
864    Number {
865        value: new_small(order, s),
866        negative: s.negative,
867        byte_order: order,
868    }
869}
870
871// Dividends of up to 64 bytes by divisors of up to 32
872
873/// The longest vector, in bytes, of a dividend that [`wider_division`] divides in registers.
874pub(super) const WIDER: usize = 64;
875
876/// Whether `a / b` is computed in registers by [`register_division`]: the dividend's vector holds
877/// at most [`WIDER`] bytes and the divisor's at most [`WIDE`].
878#[inline(always)]
879fn wide(a: &Number, b: &Number) -> bool {
880    a.value.len() <= WIDER && b.value.len() <= WIDE
881}
882
883/// The quotient and the remainder of a dividend of up to 64 bytes by a divisor of up to 32: by a
884/// divisor of up to 16 significant bytes, as [`wide_division`] computes them up to 32 bytes and
885/// [`wider_division`] beyond; by a longer one, as [`wider_by_wide`] does. Panics with the message
886/// of `%` when `REM`, of `/` otherwise, when the divisor is zero.
887///
888/// # Safety
889///
890/// As for [`wider_division`], and the divisor's vector must hold at most [`WIDE`] bytes.
891#[inline(always)]
892#[track_caller]
893unsafe fn register_division<const EUCLIDEAN: bool, const REM: bool>(
894    a: &Number,
895    b: &Number,
896) -> (Wide, Wide) {
897    // SAFETY: as the caller guarantees, with the length checked for the shorter one.
898    unsafe {
899        let y = if b.value.len() <= SMALL {
900            read_small(&b.value, b.byte_order)
901        } else {
902            let y = read_wide(&b.value, b.byte_order);
903            if y[2] | y[3] != 0 {
904                return by_medium::<EUCLIDEAN>(a, Medium::of(y, b.negative));
905            }
906            u128::from(y[0]) | (u128::from(y[1]) << 64)
907        };
908        if y == 0 {
909            by_zero::<REM>();
910        }
911        let y = Short::of(y, b.negative);
912        if a.value.len() <= WIDE {
913            wide_division::<EUCLIDEAN, 4>(a, y)
914        } else {
915            wider_division::<EUCLIDEAN>(a, y)
916        }
917    }
918}
919
920/// A divisor of up to 16 bytes, not zero, as the divisions in registers use it: its magnitude
921/// `y`, the shift `s` that sets its top bit and the magnitude so shifted, `d`, the reciprocal `v`
922/// of `d`'s top limb when `y` is one limb and of both otherwise, and its sign.
923#[derive(Clone, Copy)]
924pub(super) struct Short {
925    pub(super) y: u128,
926    s: u32,
927    d: u128,
928    v: u64,
929    negative: bool,
930}
931
932impl Short {
933    /// The magnitude `y`, not zero, and the sign `negative`, prepared.
934    #[inline(always)]
935    pub(super) fn of(y: u128, negative: bool) -> Short {
936        let (y1, y0) = ((y >> 64) as u64, y as u64);
937        let s = if y1 == 0 {
938            y0.leading_zeros()
939        } else {
940            y1.leading_zeros()
941        };
942        let d = y << s;
943        let v = if y1 == 0 {
944            invert_limb(d as u64)
945        } else {
946            invert_3by2((d >> 64) as u64, d as u64)
947        };
948        Short {
949            y,
950            s,
951            d,
952            v,
953            negative,
954        }
955    }
956}
957
958/// The quotient and the remainder of a dividend of up to `8 LIMBS` bytes, 16 or 32, by the short
959/// divisor `y`, truncated, or Euclid's with `EUCLIDEAN`, computed in registers. The dividend is
960/// read as limbs, as the addition or the multiplication reads it, shifted so that the divisor's top
961/// bit is set, and its limbs divided by [`div_2by1`] steps for a divisor of one limb, or
962/// [`div_3by2`] steps for two, unrolled.
963///
964/// # Safety
965///
966/// The dividend's vector must hold at most `8 LIMBS` bytes.
967#[inline(always)]
968pub(super) unsafe fn wide_division<const EUCLIDEAN: bool, const LIMBS: usize>(
969    a: &Number,
970    y: Short,
971) -> (Wide, Wide) {
972    // SAFETY: as the caller guarantees.
973    let x = unsafe {
974        if LIMBS == 2 {
975            let x = read_small(&a.value, a.byte_order);
976            [x as u64, (x >> 64) as u64, 0, 0]
977        } else {
978            read_wide(&a.value, a.byte_order)
979        }
980    };
981    let u = shifted(x, y.s);
982    let mut q = [0; 4];
983    let r = if y.y >> 64 == 0 {
984        let d = y.d as u64;
985        let mut t = u[LIMBS];
986        for i in (0..LIMBS).rev() {
987            (q[i], t) = div_2by1(t, u[i], d, y.v);
988        }
989        u128::from(t >> y.s)
990    } else {
991        let (d1, d0) = ((y.d >> 64) as u64, y.d as u64);
992        let (mut t1, mut t0) = (u[LIMBS], u[LIMBS - 1]);
993        for i in (0..LIMBS - 1).rev() {
994            (q[i], t1, t0) = div_3by2(t1, t0, u[i], d1, d0, y.v);
995        }
996        ((u128::from(t1) << 64) | u128::from(t0)) >> y.s
997    };
998    let negative_a = a.negative && x != [0; 4];
999    if EUCLIDEAN && negative_a && r != 0 {
1000        // One further from zero, which leaves the remainder `y - r`: with `r != 0`, `y >= 2`, and
1001        // the quotient, at most half the dividend, does not overflow.
1002        let mut carry = true;
1003        for l in &mut q {
1004            (*l, carry) = l.overflowing_add(u64::from(carry));
1005        }
1006        return wide_results::<true>(q4(q), y.y - r, a.negative != y.negative, false);
1007    }
1008    // The quotient's length without a branch by one limb, whose quotients of 24 or 25 bytes for
1009    // a dividend of 32 are a coin toss; by two, where it took 82 cycles against 75 for 32 bytes
1010    // by 16, with one.
1011    if y.y >> 64 == 0 {
1012        wide_results::<true>(q4(q), r, a.negative != y.negative, negative_a && !EUCLIDEAN)
1013    } else {
1014        wide_results::<false>(q4(q), r, a.negative != y.negative, negative_a && !EUCLIDEAN)
1015    }
1016}
1017
1018/// The four limbs `q` as eight.
1019#[inline(always)]
1020fn q4(q: [u64; 4]) -> [u64; 8] {
1021    [q[0], q[1], q[2], q[3], 0, 0, 0, 0]
1022}
1023
1024/// The quotient `q` and the remainder `r` of a division in registers as results to write, with the
1025/// signs `negative_q` and `negative_r`, which zero does not keep; the quotient's length found
1026/// without a branch with `BRANCHLESS` (see [`wide_of`]).
1027#[inline(always)]
1028fn wide_results<const BRANCHLESS: bool>(
1029    q: [u64; 8],
1030    r: u128,
1031    negative_q: bool,
1032    negative_r: bool,
1033) -> (Wide, Wide) {
1034    (
1035        wide_of::<BRANCHLESS>(q, negative_q),
1036        wide_of::<false>([r as u64, (r >> 64) as u64, 0, 0, 0, 0, 0, 0], negative_r),
1037    )
1038}
1039
1040/// [`wide_division`] for a dividend of 33 to 64 bytes: its limbs are read shifted into memory, and
1041/// divided by a loop of steps.
1042///
1043/// # Safety
1044///
1045/// The dividend's vector must hold at most [`WIDER`] bytes.
1046#[inline(always)]
1047pub(super) unsafe fn wider_division<const EUCLIDEAN: bool>(a: &Number, y: Short) -> (Wide, Wide) {
1048    let x = Operand {
1049        ptr: a.value.as_ptr(),
1050        len: a.value.len(),
1051        big_endian: a.byte_order == ByteOrder::BigEndian,
1052        significant: a.value.len(),
1053    };
1054    let n = x.len.div_ceil(8);
1055    let mut u = [0; 9];
1056    // SAFETY: the dividend's `n <= 8` limbs and the one above them fit.
1057    unsafe { u[n] = to_limbs_shifted(x, u.as_mut_ptr(), y.s) };
1058    let mut q = [0; 8];
1059    let r = if y.y >> 64 == 0 {
1060        let d = y.d as u64;
1061        let mut t = u[n];
1062        for i in (0..n).rev() {
1063            (q[i], t) = div_2by1(t, u[i], d, y.v);
1064        }
1065        u128::from(t >> y.s)
1066    } else {
1067        let (d1, d0) = ((y.d >> 64) as u64, y.d as u64);
1068        let (mut t1, mut t0) = (u[n], u[n - 1]);
1069        for i in (0..n - 1).rev() {
1070            (q[i], t1, t0) = div_3by2(t1, t0, u[i], d1, d0, y.v);
1071        }
1072        ((u128::from(t1) << 64) | u128::from(t0)) >> y.s
1073    };
1074    let negative_a = a.negative && u != [0; 9];
1075    if EUCLIDEAN && negative_a && r != 0 {
1076        // As in `wide_division`.
1077        let mut carry = true;
1078        for l in &mut q {
1079            (*l, carry) = l.overflowing_add(u64::from(carry));
1080        }
1081        return wide_results::<false>(q, y.y - r, a.negative != y.negative, false);
1082    }
1083    wide_results::<false>(q, r, a.negative != y.negative, negative_a && !EUCLIDEAN)
1084}
1085
1086/// A divisor of three or four limbs, 17 to 32 significant bytes, as [`wider_by_wide`] uses it: its
1087/// limbs `d` shifted left by `s` bits so that the top bit of the top one is set, their number
1088/// `n`, the reciprocal `v` of their top two, and its sign.
1089#[derive(Clone, Copy)]
1090pub(super) struct Medium {
1091    d: [u64; 4],
1092    s: u32,
1093    n: usize,
1094    v: u64,
1095    negative: bool,
1096}
1097
1098impl Medium {
1099    /// The magnitude of the limbs `y`, of which the third or the fourth is not zero, and the sign
1100    /// `negative`, prepared.
1101    #[inline(always)]
1102    pub(super) fn of(y: [u64; 4], negative: bool) -> Medium {
1103        let n = if y[3] != 0 { 4 } else { 3 };
1104        let s = y[n - 1].leading_zeros();
1105        let above = |l: u64| (l >> 1) >> (63 - s);
1106        let d = [
1107            y[0] << s,
1108            (y[1] << s) | above(y[0]),
1109            (y[2] << s) | above(y[1]),
1110            (y[3] << s) | above(y[2]),
1111        ];
1112        let v = invert_3by2(d[n - 1], d[n - 2]);
1113        Medium {
1114            d,
1115            s,
1116            n,
1117            v,
1118            negative,
1119        }
1120    }
1121
1122    /// The divisor normalized in the `n` limbs at `d` by the shift `s`, `n` three or four, their
1123    /// reciprocal `v`, and the sign `negative`.
1124    ///
1125    /// # Safety
1126    ///
1127    /// The limbs at `d` must be valid for reads.
1128    #[inline(always)]
1129    pub(super) unsafe fn normalized(
1130        d: *const u64,
1131        n: usize,
1132        s: u32,
1133        v: u64,
1134        negative: bool,
1135    ) -> Medium {
1136        let mut limbs = [0; 4];
1137        // SAFETY: as the caller guarantees.
1138        unsafe { ptr::copy_nonoverlapping(d, limbs.as_mut_ptr(), n) };
1139        Medium {
1140            d: limbs,
1141            s,
1142            n,
1143            v,
1144            negative,
1145        }
1146    }
1147}
1148
1149/// The quotient and the remainder of a dividend of up to 64 bytes by the divisor `y`, by
1150/// [`wider_by_wide`] for its number of limbs.
1151///
1152/// # Safety
1153///
1154/// The dividend's vector must hold at most [`WIDER`] bytes.
1155#[inline(always)]
1156pub(super) unsafe fn by_medium<const EUCLIDEAN: bool>(a: &Number, y: Medium) -> (Wide, Wide) {
1157    // SAFETY: as the caller guarantees.
1158    unsafe {
1159        if y.n == 4 {
1160            wider_by_wide::<EUCLIDEAN, 4>(a, y)
1161        } else {
1162            wider_by_wide::<EUCLIDEAN, 3>(a, y)
1163        }
1164    }
1165}
1166
1167/// The quotient and the remainder of a dividend of up to 64 bytes by the divisor `y` of `NY`
1168/// limbs, truncated, or Euclid's with `EUCLIDEAN`: the steps of the schoolbook division on limbs
1169/// in arrays, the divisor's top two and their reciprocal in registers, and the products of a
1170/// quotient limb by its other one or two limbs inline.
1171///
1172/// # Safety
1173///
1174/// The dividend's vector must hold at most [`WIDER`] bytes.
1175#[inline(always)]
1176unsafe fn wider_by_wide<const EUCLIDEAN: bool, const NY: usize>(
1177    a: &Number,
1178    y: Medium,
1179) -> (Wide, Wide) {
1180    debug_assert!(y.n == NY);
1181    let (ny, d, s, v) = (NY, y.d, y.s, y.v);
1182    let x = Operand {
1183        ptr: a.value.as_ptr(),
1184        len: a.value.len(),
1185        big_endian: a.byte_order == ByteOrder::BigEndian,
1186        significant: a.value.len(),
1187    };
1188    let n = x.len.div_ceil(8);
1189    let mut u = [0; 9];
1190    // SAFETY: the dividend's `n <= 8` limbs and the one above them fit.
1191    unsafe { u[n] = to_limbs_shifted(x, u.as_mut_ptr(), s) };
1192    let negative_a = a.negative && u != [0; 9];
1193    let (d1, d0) = (d[ny - 1], d[ny - 2]);
1194    let mut q = [0; 8];
1195    let nn = n.max(ny);
1196    // Without bits shifted out above the dividend, the top quotient limb is 0 or 1, from a
1197    // comparison instead of a step, as for the general path.
1198    let steps = if u[nn] == 0 {
1199        let k = nn - ny;
1200        if (0..ny)
1201            .rev()
1202            .map(|j| u[k + j].cmp(&d[j]))
1203            .find(|o| o.is_ne())
1204            != Some(Less)
1205        {
1206            let mut borrow = false;
1207            for j in 0..ny {
1208                let (l, b1) = u[k + j].overflowing_sub(d[j]);
1209                let (l, b2) = l.overflowing_sub(u64::from(borrow));
1210                (u[k + j], borrow) = (l, b1 | b2);
1211            }
1212            q[k] = 1;
1213        }
1214        k
1215    } else {
1216        nn - ny + 1
1217    };
1218    // The limb above the dividend's is below `d1`, whose top bit is set, and each step leaves the
1219    // partial remainder below the divisor: the top two limbs of a step are at most `d1 B + d0`.
1220    for i in (0..steps).rev() {
1221        let (u2, u1) = (u[i + ny], u[i + ny - 1]);
1222        if u2 == d1 && u1 == d0 {
1223            q[i] = all_ones_step(&mut u, i, &d, ny);
1224            continue;
1225        }
1226        let (mut qi, mut r1, mut r0) = div_3by2(u2, u1, u[i + ny - 2], d1, d0, v);
1227        // The quotient limb times the divisor's limbs below its top two.
1228        let mut borrow = 0;
1229        for j in 0..ny - 2 {
1230            let p = u128::from(qi) * u128::from(d[j]) + u128::from(borrow);
1231            let (l, b) = u[i + j].overflowing_sub(p as u64);
1232            u[i + j] = l;
1233            borrow = (p >> 64) as u64 + u64::from(b);
1234        }
1235        let b0;
1236        (r0, b0) = r0.overflowing_sub(borrow);
1237        let b1;
1238        (r1, b1) = r1.overflowing_sub(u64::from(b0));
1239        if b1 {
1240            // One too large: the divisor is added back.
1241            let mut carry = false;
1242            for j in 0..ny - 2 {
1243                (u[i + j], carry) = carrying(u[i + j], d[j], carry);
1244            }
1245            (r0, carry) = carrying(r0, d0, carry);
1246            r1 = r1.wrapping_add(d1).wrapping_add(u64::from(carry));
1247            qi -= 1;
1248        }
1249        (u[i + ny - 2], u[i + ny - 1], u[i + ny]) = (r0, r1, 0);
1250        q[i] = qi;
1251    }
1252    let remainder = u[..ny] != [0; NY];
1253    if EUCLIDEAN && negative_a && remainder {
1254        // One further from zero, which leaves the remainder `y - r`, from the limbs as they are
1255        // shifted: the quotient, below `B^6` as the divisor is at least `B^2`, does not overflow.
1256        let mut carry = true;
1257        for l in &mut q {
1258            (*l, carry) = l.overflowing_add(u64::from(carry));
1259        }
1260        let mut borrow = false;
1261        for j in 0..ny {
1262            let (l, b1) = d[j].overflowing_sub(u[j]);
1263            let (l, b2) = l.overflowing_sub(u64::from(borrow));
1264            (u[j], borrow) = (l, b1 | b2);
1265        }
1266    }
1267    // The remainder, shifted back: `(l << 1) << (63 - s)` is `l << (64 - s)`, and zero for `s = 0`.
1268    let below = |l: u64| (l << 1) << (63 - s);
1269    let mut r = [0; 8];
1270    for j in 0..ny {
1271        r[j] = (u[j] >> s) | below(u[j + 1]);
1272    }
1273    (
1274        wide_of::<false>(q, a.negative != y.negative),
1275        wide_of::<false>(r, negative_a && !EUCLIDEAN),
1276    )
1277}
1278
1279/// `a + b + carry` and its carry out.
1280#[inline(always)]
1281fn carrying(a: u64, b: u64, carry: bool) -> (u64, bool) {
1282    let (s, c1) = a.overflowing_add(b);
1283    let (s, c2) = s.overflowing_add(u64::from(carry));
1284    (s, c1 | c2)
1285}
1286
1287/// The step of [`wider_by_wide`] whose partial remainder, in limbs `i..=i + ny` of `u`, has the
1288/// top two limbs of the normalized divisor `d` of `ny` limbs, which `div_3by2` cannot divide: its
1289/// quotient limb is `B - 1`, as in `sb_div_qr`, and `(B - 1) d` is subtracted, which cancels the
1290/// top limb. Returns the quotient limb.
1291#[cold]
1292#[inline(never)]
1293fn all_ones_step(u: &mut [u64; 9], i: usize, d: &[u64; 4], ny: usize) -> u64 {
1294    // `(B - 1) d = d B - d`: `d` added, and `d` subtracted one limb up.
1295    let mut carry = false;
1296    for j in 0..ny {
1297        (u[i + j], carry) = carrying(u[i + j], d[j], carry);
1298    }
1299    u[i + ny] = u[i + ny].wrapping_add(u64::from(carry));
1300    let mut borrow = false;
1301    for j in 0..ny {
1302        let (l, b1) = u[i + j + 1].overflowing_sub(d[j]);
1303        let (l, b2) = l.overflowing_sub(u64::from(borrow));
1304        (u[i + j + 1], borrow) = (l, b1 | b2);
1305    }
1306    debug_assert!(u[i + ny] == 0, "the top limb cancels");
1307    u64::MAX
1308}
1309
1310/// The four limbs `x` shifted left by `s` bits, `s < 64`, into five.
1311#[inline(always)]
1312fn shifted(x: [u64; 4], s: u32) -> [u64; 5] {
1313    // `(l >> 1) >> (63 - s)` is `l >> (64 - s)`, and zero for `s = 0`, with shifts below 64.
1314    let out = |l: u64| (l >> 1) >> (63 - s);
1315    [
1316        x[0] << s,
1317        (x[1] << s) | out(x[0]),
1318        (x[2] << s) | out(x[1]),
1319        (x[3] << s) | out(x[2]),
1320        out(x[3]),
1321    ]
1322}
1323
1324/// The limbs `l` as a result of a division in registers, with its length in the shortest form
1325/// and the sign `negative`, which zero does not keep; the length found without a branch with
1326/// `BRANCHLESS`.
1327///
1328/// Whether a quotient's top limb is zero is as good as random, and a mispredicted branch on it
1329/// cost a third of a division of 32 bytes by 8, measured on an Apple M4 Max: 77 cycles against
1330/// 65. That is for the quotient of [`wide_division`], whose limbs are in registers; for those of
1331/// [`wider_division`] and [`wider_by_wide`], in memory, the length found without a branch made
1332/// the stores of the result wait for all of them, and a division of 64 bytes by 8 took 160
1333/// cycles against 110.
1334#[inline(always)]
1335fn wide_of<const BRANCHLESS: bool>(l: [u64; 8], negative: bool) -> Wide {
1336    let len = if BRANCHLESS {
1337        // The top limb that is not zero, `t`, from a bit for each, and its bytes; zero is one
1338        // byte, of limb 0.
1339        let mut nonzero = 1;
1340        for (i, &x) in l.iter().enumerate() {
1341            nonzero |= u32::from(x != 0) << i;
1342        }
1343        let t = 31 - nonzero.leading_zeros() as usize;
1344        (8 * t + 8 - l[t].leading_zeros() as usize / 8).max(1)
1345    } else {
1346        match l.iter().rposition(|&x| x != 0) {
1347            Some(t) => 8 * t + 8 - l[t].leading_zeros() as usize / 8,
1348            None => 1,
1349        }
1350    };
1351    Wide {
1352        limbs: l,
1353        len,
1354        negative: negative && l != [0; 8],
1355    }
1356}
1357
1358/// The result `w` of [`wide_division`] as a number in one new vector of exactly its length.
1359#[inline(always)]
1360pub(super) fn wide_number(order: ByteOrder, w: &Wide) -> Number {
1361    let mut value = Vec::new();
1362    put_wide(&mut value, order, w);
1363    Number {
1364        value,
1365        negative: w.negative,
1366        byte_order: order,
1367    }
1368}
1369
1370// The general path: operands of more than 16 bytes, out of line, so that the small path saves no
1371// registers for it.
1372
1373/// The operands of a division with at least one of more than 16 bytes, read for the general path;
1374/// panics with the message of `%` when `REM`, of `/` otherwise, when the divisor is zero.
1375#[inline(always)]
1376#[track_caller]
1377fn operands<const REM: bool>(a: &Number, b: &Number) -> (Operand, Operand) {
1378    let (x, y) = (Operand::of(a), Operand::of(b));
1379    if y.significant == 0 {
1380        by_zero::<REM>();
1381    }
1382    (x, y)
1383}
1384
1385/// `a / b` (`a % b` when `REM`; Euclid's with `EUCLIDEAN`) for borrowed operands, in one new
1386/// vector.
1387#[inline(never)]
1388#[track_caller]
1389fn ref_by_ref<const EUCLIDEAN: bool, const REM: bool>(a: &Number, b: &Number) -> Number {
1390    let order = a.byte_order;
1391    if wide(a, b) {
1392        // SAFETY: the vectors hold at most 64 and 32 bytes.
1393        let (q, r) = unsafe { register_division::<EUCLIDEAN, REM>(a, b) };
1394        return wide_number(order, if REM { &r } else { &q });
1395    }
1396    let (x, y) = operands::<REM>(a, b);
1397    // SAFETY: the operands are those of `a` and `b`, which are borrowed until the result is
1398    // computed.
1399    unsafe {
1400        divide::<EUCLIDEAN, _>(
1401            x,
1402            y,
1403            a.negative,
1404            b.negative,
1405            Want::of(EUCLIDEAN, REM),
1406            |q, r| new_number(if REM { r } else { q }, order),
1407        )
1408    }
1409}
1410
1411/// `div_rem` for borrowed operands: both results, in one new vector each.
1412#[inline(never)]
1413#[track_caller]
1414fn both<const EUCLIDEAN: bool>(a: &Number, b: &Number) -> (Number, Number) {
1415    let order = a.byte_order;
1416    if wide(a, b) {
1417        // SAFETY: the vectors hold at most 64 and 32 bytes.
1418        let (q, r) = unsafe { register_division::<EUCLIDEAN, false>(a, b) };
1419        return (wide_number(order, &q), wide_number(order, &r));
1420    }
1421    let (x, y) = operands::<false>(a, b);
1422    // SAFETY: as in `ref_by_ref`.
1423    unsafe {
1424        divide::<EUCLIDEAN, _>(x, y, a.negative, b.negative, Want::Both, |q, r| {
1425            (new_number(q, order), new_number(r, order))
1426        })
1427    }
1428}
1429
1430/// `a / b` (`a % b` when `REM`) for a borrowed `a` and an owned `b`: the result takes the vector of
1431/// `b` when it is built there, leaving `b` an empty one; the caller drops `b` either way.
1432#[inline(never)]
1433#[track_caller]
1434fn ref_by_value<const REM: bool>(a: &Number, b: &mut Number) -> Number {
1435    let order = a.byte_order;
1436    if wide(a, b) {
1437        // SAFETY: the vectors hold at most 64 and 32 bytes.
1438        let (q, r) = unsafe { register_division::<TRUNCATED, REM>(a, b) };
1439        let w = if REM { &r } else { &q };
1440        put_wide(&mut b.value, order, w);
1441        return Number {
1442            value: mem::take(&mut b.value),
1443            negative: w.negative,
1444            byte_order: order,
1445        };
1446    }
1447    let (x, y) = operands::<REM>(a, b);
1448    // SAFETY: the operands are those of `a` and `b`; `b`'s vector is written only once both are
1449    // read into limbs.
1450    unsafe {
1451        divide::<TRUNCATED, _>(
1452            x,
1453            y,
1454            a.negative,
1455            b.negative,
1456            Want::of(TRUNCATED, REM),
1457            |q, r| {
1458                let p = if REM { r } else { q };
1459                p.put_in(&mut b.value, order);
1460                Number {
1461                    value: mem::take(&mut b.value),
1462                    negative: p.negative,
1463                    byte_order: order,
1464                }
1465            },
1466        )
1467    }
1468}
1469
1470/// `a /= b` (`a %= b` when `REM`) for a borrowed `b`.
1471#[inline(never)]
1472#[track_caller]
1473fn assign_ref<const REM: bool>(a: &mut Number, b: &Number) {
1474    let order = a.byte_order;
1475    if wide(a, b) {
1476        // SAFETY: the vectors hold at most 64 and 32 bytes.
1477        let (q, r) = unsafe { register_division::<TRUNCATED, REM>(a, b) };
1478        let w = if REM { &r } else { &q };
1479        put_wide(&mut a.value, order, w);
1480        a.negative = w.negative;
1481        return;
1482    }
1483    let (x, y) = operands::<REM>(a, b);
1484    // SAFETY: the operands are those of `a` and `b`; `a`'s vector is written only once both are
1485    // read into limbs.
1486    unsafe {
1487        divide::<TRUNCATED, _>(
1488            x,
1489            y,
1490            a.negative,
1491            b.negative,
1492            Want::of(TRUNCATED, REM),
1493            |q, r| {
1494                let p = if REM { r } else { q };
1495                p.put_in(&mut a.value, order);
1496                a.negative = p.negative;
1497            },
1498        );
1499    }
1500}
1501
1502/// `a /= b` (`a %= b` when `REM`) for an owned `b`: when the result is built in the vector of `b`,
1503/// the vector of `a` goes to `b`; the caller drops `b` either way.
1504#[inline(never)]
1505#[track_caller]
1506fn assign_value<const REM: bool>(a: &mut Number, b: &mut Number) {
1507    let order = a.byte_order;
1508    if wide(a, b) {
1509        // SAFETY: the vectors hold at most 64 and 32 bytes.
1510        let (q, r) = unsafe { register_division::<TRUNCATED, REM>(a, b) };
1511        let w = if REM { &r } else { &q };
1512        if a.value.capacity() < w.len && b.value.capacity() >= w.len {
1513            mem::swap(&mut a.value, &mut b.value);
1514        }
1515        put_wide(&mut a.value, order, w);
1516        a.negative = w.negative;
1517        return;
1518    }
1519    let (x, y) = operands::<REM>(a, b);
1520    // SAFETY: as in `assign_ref`.
1521    unsafe {
1522        divide::<TRUNCATED, _>(
1523            x,
1524            y,
1525            a.negative,
1526            b.negative,
1527            Want::of(TRUNCATED, REM),
1528            |q, r| {
1529                let p = if REM { r } else { q };
1530                if a.value.capacity() < p.len && b.value.capacity() >= p.len {
1531                    mem::swap(&mut a.value, &mut b.value);
1532                }
1533                p.put_in(&mut a.value, order);
1534                a.negative = p.negative;
1535            },
1536        );
1537    }
1538}
1539
1540/// The result `p` as a number in one new vector of exactly its length, in the byte order `order`.
1541///
1542/// # Safety
1543///
1544/// As for [`Product::write`].
1545#[inline(always)]
1546unsafe fn new_number(p: &Product, order: ByteOrder) -> Number {
1547    let mut v = Vec::with_capacity(p.len);
1548    // SAFETY: the new vector has room for the `len` bytes, all of which are written before the
1549    // length is set.
1550    unsafe {
1551        p.write(v.as_mut_ptr(), order);
1552        v.set_len(p.len);
1553    }
1554    Number {
1555        value: v,
1556        negative: p.negative,
1557        byte_order: order,
1558    }
1559}
1560
1561/// Divides the operand `x` by the operand `y`, of signs `negative_x` and `negative_y`, and hands
1562/// the quotient and the remainder to `place`, which writes them where they belong; returns what
1563/// `place` returns. The division is truncated, or Euclid's with `EUCLIDEAN`. When `want` asks for
1564/// one result alone, the other is not computed, and `place` gets zero for it.
1565///
1566/// # Safety
1567///
1568/// The operands must describe vectors that stay valid for reads until `place` is called, and `y`
1569/// must not be zero.
1570#[inline(always)]
1571unsafe fn divide<const EUCLIDEAN: bool, R>(
1572    x: Operand,
1573    y: Operand,
1574    negative_x: bool,
1575    negative_y: bool,
1576    want: Want,
1577    place: impl FnOnce(&Product, &Product) -> R,
1578) -> R {
1579    let ny = y.significant.div_ceil(8);
1580    if ny == 1 && want == Want::Remainder && x.significant >= REM_1_BYTES.min(REM_1_BYTES_WIDE) {
1581        // SAFETY: the divisor has one limb.
1582        let d = unsafe { limb_of(y) };
1583        let from = if d <= REM_1_MAX {
1584            REM_1_BYTES
1585        } else {
1586            REM_1_BYTES_WIDE
1587        };
1588        if d >= 2 && x.significant >= from {
1589            // SAFETY: as the caller guarantees.
1590            let r = unsafe { rem_1(x, &Powers::of(d)) };
1591            return remainder_of_1::<EUCLIDEAN, R>(r, d, negative_x && x.significant != 0, place);
1592        }
1593    }
1594    let nx = x.significant.div_ceil(8).max(ny);
1595    // The divisor, normalized, and a limb to start it on 16 bytes, then what `compute_by` needs.
1596    let need = ny + 1 + working_memory(nx, ny, want);
1597    let compute = |s: *mut MaybeUninit<u64>| {
1598        // SAFETY: the working memory holds `need` limbs; the rest as the caller guarantees.
1599        unsafe { compute::<EUCLIDEAN, R>(s.cast(), x, y, negative_x, negative_y, want, place) }
1600    };
1601    if need <= STACK_LIMBS {
1602        on_stack(compute)
1603    } else {
1604        on_heap(need, compute)
1605    }
1606}
1607
1608/// Hands the remainder `r` by the one-limb divisor `d` of a dividend of sign `negative_x` (not set
1609/// for zero) to `place`, with zero for the quotient: truncated, or Euclid's with `EUCLIDEAN`.
1610#[inline(always)]
1611pub(super) fn remainder_of_1<const EUCLIDEAN: bool, R>(
1612    r: u64,
1613    d: u64,
1614    negative_x: bool,
1615    place: impl FnOnce(&Product, &Product) -> R,
1616) -> R {
1617    let r = if EUCLIDEAN && negative_x && r != 0 {
1618        d - r
1619    } else {
1620        r
1621    };
1622    let remainder = Product {
1623        r: if r == 0 { ptr::null() } else { &r },
1624        len: 8 - (r | 1).leading_zeros() as usize / 8,
1625        negative: negative_x && !EUCLIDEAN && r != 0,
1626    };
1627    place(&ZERO, &remainder)
1628}
1629
1630/// The limbs of working memory that [`compute_by`] needs for a dividend of `nx` limbs, at least as
1631/// many as the divisor's `ny`: the dividend shifted, with a limb above it, the quotient with a limb
1632/// above it for Euclid's, and the scratch of divide and conquer, or of a quotient alone computed
1633/// from the top limbs of the operands.
1634#[inline(always)]
1635pub(super) fn working_memory(nx: usize, ny: usize, want: Want) -> usize {
1636    let qn = nx - ny + 1;
1637    let mut need = (nx + 1) + (qn + 1);
1638    if want == Want::Quotient && ny >= 3 && from_top(nx + 1, ny) {
1639        // The top limbs of both operands, a limb to align the divisor's, their quotient and the
1640        // scratch of their division; or the product that checks it.
1641        let k = qn;
1642        let top = (2 * k + 2) + 1 + 2 * (k + 1) + top_itch(k);
1643        need += top.max(check_itch(nx + 1, ny));
1644    } else if ny >= DC_DIV {
1645        // The exact division by divide and conquer, of the dividend with the limb above it or
1646        // without (see `compute_by`), and for a quotient alone of its top limbs, or with the low
1647        // ones from the top ones; below `DC_DIV` limbs, none.
1648        let itch = |nn: usize| {
1649            let mut itch = qr_itch(nn, ny);
1650            if want == Want::Quotient && ny >= 3 {
1651                if mu(nn, ny) {
1652                    // Newton's method allocates its own.
1653                } else if ny < DC_DIV_Q {
1654                    itch = itch.max(q_itch(nn, ny));
1655                } else if let l @ 1.. = split_low(nn, ny) {
1656                    itch = itch.max(split_itch(nn, ny, l));
1657                }
1658            }
1659            itch
1660        };
1661        need += itch(nx + 1).max(itch(nx));
1662    }
1663    need
1664}
1665
1666/// A divisor of the general path as the division reads it: its `n` limbs at `d`, the least
1667/// significant first, shifted left by `shift` bits so that the top bit is set, starting on 16
1668/// bytes, and their reciprocal `v`, of the top limb for one limb and of the top two otherwise;
1669/// and what a [`Divisor`](super::Divisor) keeps for Newton's method, when it has it, at `pre`
1670/// (null otherwise).
1671#[derive(Clone, Copy)]
1672pub(super) struct Normal {
1673    pub(super) d: *const u64,
1674    pub(super) n: usize,
1675    pub(super) shift: u32,
1676    pub(super) v: u64,
1677    pub(super) pre: *const Prepared,
1678}
1679
1680/// The shift that sets the top bit of the operand `y`, not zero, from its most significant byte,
1681/// which is its top limb's `y.significant - 8 (n - 1)`-th.
1682///
1683/// # Safety
1684///
1685/// The operand's vector must be valid for reads.
1686#[inline(always)]
1687unsafe fn normalizing_shift(y: Operand) -> u32 {
1688    // SAFETY: the most significant byte lies inside the vector.
1689    let top = unsafe {
1690        if y.big_endian {
1691            *y.ptr.add(y.len - y.significant)
1692        } else {
1693            *y.ptr.add(y.significant - 1)
1694        }
1695    };
1696    8 * (8 * y.significant.div_ceil(8) - y.significant) as u32 + top.leading_zeros()
1697}
1698
1699/// Reads the divisor `y`, not zero, normalized into its limbs at `d`, which start on 16 bytes, and
1700/// computes their reciprocal.
1701///
1702/// # Safety
1703///
1704/// The operand's vector must be valid for reads and `d` for writing its limbs.
1705#[inline(always)]
1706pub(super) unsafe fn normalize(y: Operand, d: *mut u64) -> Normal {
1707    let n = y.significant.div_ceil(8);
1708    // SAFETY: as the caller guarantees.
1709    unsafe {
1710        let shift = normalizing_shift(y);
1711        to_limbs_shifted(y, d, shift);
1712        let v = if n == 1 {
1713            invert_limb(*d)
1714        } else {
1715            invert_3by2(*d.add(n - 1), *d.add(n - 2))
1716        };
1717        Normal {
1718            d,
1719            n,
1720            shift,
1721            v,
1722            pre: ptr::null(),
1723        }
1724    }
1725}
1726
1727/// [`divide`] in the working memory at `s`: the divisor is read into its first limbs, normalized,
1728/// and the dividend divided by it with [`compute_by`] in the rest, but for a quotient alone much
1729/// shorter than the divisor, which needs only the divisor's top limbs.
1730///
1731/// # Safety
1732///
1733/// As for [`divide`], with `s` valid for the limbs that `divide` counts.
1734#[inline(always)]
1735unsafe fn compute<const EUCLIDEAN: bool, R>(
1736    s: *mut u64,
1737    x: Operand,
1738    y: Operand,
1739    negative_x: bool,
1740    negative_y: bool,
1741    want: Want,
1742    place: impl FnOnce(&Product, &Product) -> R,
1743) -> R {
1744    let ny = y.significant.div_ceil(8);
1745    let nx = x.significant.div_ceil(8).max(ny);
1746    // SAFETY: the working memory holds the divisor's `ny` limbs from an address on 16 bytes, and
1747    // after them the limbs of `compute_by`.
1748    unsafe {
1749        // The divisor starts on 16 bytes, which the kernel reads in pairs of limbs for every limb
1750        // of the quotient: at 8 bytes off, a division of 72 limbs by 36 took 4100 cycles instead of
1751        // 2760 on an Apple M4 Max, whenever the stack put it there.
1752        let d = s.add((s.addr() / 8) & 1);
1753        let w = s.add(ny + 1);
1754        if want == Want::Quotient && ny >= 3 && from_top(nx + 1, ny) {
1755            let k = nx + 1 - ny;
1756            let (u, q) = (w, w.add(nx + 1));
1757            let t = q.add(k + 1);
1758            let shift = normalizing_shift(y);
1759            quotient_from_top(x, Top::Operand(y, d), ny, shift, u, q, t);
1760            let quotient = result(q, k, (negative_x && x.significant != 0) != negative_y);
1761            return place(&quotient, &ZERO);
1762        }
1763        let normal = normalize(y, d);
1764        compute_by::<EUCLIDEAN, R>(w, x, normal, negative_x, negative_y, want, place)
1765    }
1766}
1767
1768/// Divides the operand `x`, of sign `negative_x`, by the normalized divisor `y`, of sign
1769/// `negative_y`, in the working memory at `s`, and hands the results to `place`, as [`divide`]
1770/// does.
1771///
1772/// # Safety
1773///
1774/// As for [`divide`], with `s` valid for the [`working_memory`] limbs of `x` and `y`.
1775#[inline(always)]
1776pub(super) unsafe fn compute_by<const EUCLIDEAN: bool, R>(
1777    s: *mut u64,
1778    x: Operand,
1779    y: Normal,
1780    negative_x: bool,
1781    negative_y: bool,
1782    want: Want,
1783    place: impl FnOnce(&Product, &Product) -> R,
1784) -> R {
1785    let (d, ny, shift) = (y.d, y.n, y.shift);
1786    let lx = x.significant.div_ceil(8);
1787    let nx = lx.max(ny);
1788    let qn = nx - ny + 1;
1789    let negative_x = negative_x && x.significant != 0;
1790    // SAFETY: the working memory holds the `nx + 1` limbs of the dividend, the `qn + 1` of the
1791    // quotient and the scratch, which every step stays inside.
1792    unsafe {
1793        let u = s;
1794        let q = u.add(nx + 1);
1795        let t = q.add(qn + 1);
1796        if want == Want::Quotient && ny >= 3 && from_top(nx + 1, ny) {
1797            quotient_from_top(x, Top::Normal(d), ny, shift, u, q, t);
1798            let quotient = result(q, qn, negative_x != negative_y);
1799            return place(&quotient, &ZERO);
1800        }
1801        read_dividend(x, u, nx, shift);
1802        *q.add(qn) = 0;
1803        match ny {
1804            1 => {
1805                *u = if want == Want::Remainder {
1806                    div_qr_1::<false>(q, u, nx, *u.add(nx), *d, y.v)
1807                } else {
1808                    div_qr_1::<true>(q, u, nx, *u.add(nx), *d, y.v)
1809                };
1810            }
1811            2 => {
1812                let (r1, r0) = div_qr_2(q, u, nx + 1, *d.add(1), *d, y.v);
1813                (*u, *u.add(1)) = (r0, r1);
1814            }
1815            _ => {
1816                // The limb above the dividend takes part only when the shift put bits in it; the
1817                // quotient's top limb then comes out of the steps, and otherwise from the
1818                // comparison that precedes them.
1819                let nn = if *u.add(nx) != 0 { nx + 1 } else { nx };
1820                let qh = if !y.pre.is_null() && mu_prepared(nn, ny) {
1821                    // A divisor's inverse and transforms, kept for its divisions.
1822                    mu_div_prepared(q, u, nn, d, ny, y.v, &*y.pre, want != Want::Quotient)
1823                } else if want != Want::Quotient {
1824                    div_qr(q, u, nn, d, ny, y.v, t)
1825                } else if mu(nn, ny) {
1826                    // The quotient alone by Newton's method, whose last block skips its remainder.
1827                    mu_div_q(q, u, nn, d, ny)
1828                } else if ny < DC_DIV_Q {
1829                    // The quotient alone: its last limbs from a shrinking divisor, the others
1830                    // exactly.
1831                    match div_q(q, u, nn, d, ny, y.v, t) {
1832                        Some(qh) => qh,
1833                        None => exactly_after_all(q, u, nn, x, y, t),
1834                    }
1835                } else if split_low(nn, ny) > 0 {
1836                    // The quotient alone of a long division: its low limbs from the top ones.
1837                    div_q_split(q, u, nn, d, ny, y.v, t)
1838                } else {
1839                    div_qr(q, u, nn, d, ny, y.v, t)
1840                };
1841                if nn == nx {
1842                    *q.add(nx - ny) = u64::from(qh);
1843                }
1844            }
1845        }
1846        if want == Want::Quotient {
1847            let quotient = result(q, qn + 1, negative_x != negative_y);
1848            return place(&quotient, &ZERO);
1849        }
1850        let remainder = (0..ny).any(|i| *u.add(i) != 0);
1851        if EUCLIDEAN && negative_x && remainder {
1852            // Euclid's quotient is one further from zero, and its remainder `|y| - r`: shifted, as
1853            // the divisor and the remainder still are.
1854            sub_n(u, d, u, ny);
1855            if want != Want::Remainder {
1856                add_1(q, qn + 1, 1);
1857            }
1858        }
1859        if shift != 0 {
1860            rshift(u, ny, shift);
1861        }
1862        // Without the quotient, the limbs of a quotient of a divisor of one limb are not written.
1863        let quotient = if want == Want::Remainder {
1864            ZERO
1865        } else {
1866            result(q, qn + 1, negative_x != negative_y)
1867        };
1868        let remainder = result(u, ny, negative_x && !EUCLIDEAN);
1869        place(&quotient, &remainder)
1870    }
1871}
1872
1873/// Reads the dividend `x` into the `nx + 1` limbs at `u`, shifted left by `shift` bits, `nx` at
1874/// least its limbs: a dividend shorter than the divisor gets zero limbs up to the divisor's length,
1875/// and its quotient is then zero, its remainder the dividend.
1876///
1877/// # Safety
1878///
1879/// The operand's vector must be valid for reads, and `u` for writing `nx + 1` limbs.
1880#[inline(always)]
1881unsafe fn read_dividend(x: Operand, u: *mut u64, nx: usize, shift: u32) {
1882    let lx = x.significant.div_ceil(8);
1883    // SAFETY: as the caller guarantees.
1884    unsafe {
1885        *u.add(lx) = to_limbs_shifted(x, u, shift);
1886        if lx < nx {
1887            ptr::write_bytes(u.add(lx + 1), 0, nx - lx);
1888        }
1889    }
1890}
1891
1892/// The quotient of [`div_qr`] after all, when [`div_q`] gave up on the dividend `x` of `nn`
1893/// limbs by the divisor `y`: the dividend is read again into the limbs at `u`. Returns the
1894/// quotient's limb above the `nn - y.n` at `q`.
1895///
1896/// # Safety
1897///
1898/// As for `div_qr`, with the operand's vector valid for reads.
1899#[cold]
1900#[inline(never)]
1901unsafe fn exactly_after_all(
1902    q: *mut u64,
1903    u: *mut u64,
1904    nn: usize,
1905    x: Operand,
1906    y: Normal,
1907    t: *mut u64,
1908) -> bool {
1909    // SAFETY: as the caller guarantees: the limbs are those `compute_by` read, of which the
1910    // division takes `nn`.
1911    unsafe {
1912        read_dividend(x, u, x.significant.div_ceil(8).max(y.n), y.shift);
1913        div_qr(q, u, nn, y.d, y.n, y.v, t)
1914    }
1915}
1916
1917/// Where [`quotient_from_top`] gets the divisor from: an operand, of which it reads only the top
1918/// limbs, and the whole, into the limbs at the pointer, for the rare check; or normalized limbs.
1919#[derive(Clone, Copy)]
1920enum Top {
1921    Operand(Operand, *mut u64),
1922    Normal(*const u64),
1923}
1924
1925/// The quotient alone of a division whose quotient is much shorter than the divisor
1926/// ([`from_top`]), in the `k` limbs at `q`: from the top `2k + 2` limbs of the dividend and the top
1927/// `k + 1` of the divisor of `ny` limbs, shifted by `shift`, by [`div_q_top`]. The whole dividend
1928/// is read, into the limbs at `u`, only for the rare check. Out of line, so that the shorter
1929/// divisions keep their registers.
1930///
1931/// # Safety
1932///
1933/// As for [`compute_by`], with `u` valid for the dividend's `nx + 1` limbs, `q` for the quotient's
1934/// `k`, and `t` for the scratch of `div_q_top` and of `check_q_top`, as [`working_memory`] counts
1935/// them, and the divisor's limbs as `y` describes them.
1936#[inline(never)]
1937unsafe fn quotient_from_top(
1938    x: Operand,
1939    y: Top,
1940    ny: usize,
1941    shift: u32,
1942    u: *mut u64,
1943    q: *mut u64,
1944    t: *mut u64,
1945) {
1946    let lx = x.significant.div_ceil(8);
1947    let nx = lx.max(ny);
1948    let k = nx + 1 - ny;
1949    // SAFETY: the copies of the top limbs, their quotient and the scratch of their division lie in
1950    // the scratch at `t`, as `working_memory` counts it, and so does the check's.
1951    unsafe {
1952        let w = t;
1953        let dt = w.add(2 * k + 2);
1954        let dt = dt.add((dt.addr() / 8) & 1);
1955        let h = dt.add(k + 1);
1956        let top: *const u64 = match y {
1957            Top::Operand(y, _) => {
1958                shifted_limbs(y, ny - (k + 1), ny, shift, dt);
1959                dt
1960            }
1961            Top::Normal(d) => d.add(ny - (k + 1)),
1962        };
1963        shifted_limbs(x, nx + 1 - (2 * k + 2), nx + 1, shift, w);
1964        let v = invert_3by2(*top.add(k), *top.add(k - 1));
1965        let found = div_q_top(h, w, k, top, v, h.add(k + 1));
1966        debug_assert!(
1967            found != Found::AllOnes,
1968            "the dividend's top limb is below the divisor's"
1969        );
1970        ptr::copy_nonoverlapping(h.add(1), q, k);
1971        if found == Found::Check {
1972            read_dividend(x, u, nx, shift);
1973            let d = match y {
1974                Top::Operand(y, d) => {
1975                    to_limbs_shifted(y, d, shift);
1976                    d.cast_const()
1977                }
1978                Top::Normal(d) => d,
1979            };
1980            check_q_top(q, u, nx + 1, d, ny, t);
1981        }
1982    }
1983}
1984
1985/// What a division on the general path computes: both results, or the quotient or the remainder
1986/// alone, which spares the steps that only the other needs.
1987#[derive(Clone, Copy, PartialEq)]
1988pub(super) enum Want {
1989    Both,
1990    Quotient,
1991    Remainder,
1992}
1993
1994impl Want {
1995    /// What `/` and `/=` (`%` and `%=` with `REM`) need, or, with `EUCLIDEAN`, `div_euclid` and
1996    /// `rem_euclid`: a Euclidean result is adjusted with both.
1997    #[inline(always)]
1998    pub(super) const fn of(euclidean: bool, rem: bool) -> Want {
1999        match (euclidean, rem) {
2000            (false, false) => Want::Quotient,
2001            (_, true) => Want::Remainder,
2002            (true, false) => Want::Both,
2003        }
2004    }
2005}
2006
2007/// The zero that [`compute`] hands to `place` as the result it does not compute.
2008const ZERO: Product = Product {
2009    r: ptr::null(),
2010    len: 1,
2011    negative: false,
2012};
2013
2014/// Limb `i` of the magnitude of the operand `x`: its `x.significant.div_ceil(8)` limbs read as
2015/// [`to_limbs_shifted`] reads them, and zero above them.
2016///
2017/// # Safety
2018///
2019/// The operand's vector must be valid for reads.
2020#[inline(always)]
2021unsafe fn limb(x: Operand, i: usize) -> u64 {
2022    let l = x.significant;
2023    let (full, rem) = (l / 8, l % 8);
2024    // SAFETY: every read lies inside the significant bytes, as in `to_limbs_shifted`.
2025    unsafe {
2026        let end = x.ptr.add(x.len);
2027        if i < full {
2028            if x.big_endian {
2029                u64::from_be_bytes(read(end.sub(8 * i + 8)))
2030            } else {
2031                u64::from_le_bytes(read(x.ptr.add(8 * i)))
2032            }
2033        } else if i == full && rem > 0 {
2034            if l >= 8 {
2035                let v = if x.big_endian {
2036                    u64::from_be_bytes(read(end.sub(l)))
2037                } else {
2038                    u64::from_le_bytes(read(x.ptr.add(l - 8)))
2039                };
2040                v >> (8 * (8 - rem))
2041            } else if x.big_endian {
2042                read_small(
2043                    core::slice::from_raw_parts(end.sub(l), rem),
2044                    ByteOrder::BigEndian,
2045                ) as u64
2046            } else {
2047                read_small(
2048                    core::slice::from_raw_parts(x.ptr, rem),
2049                    ByteOrder::LittleEndian,
2050                ) as u64
2051            }
2052        } else {
2053            0
2054        }
2055    }
2056}
2057
2058/// Writes limbs `from..to` of the magnitude of the operand `x` shifted left by `s` bits, `s < 64`,
2059/// at `out`: each from the limb at its place and the one below it. The whole limbs go through a
2060/// loop of their own, for either byte order, and the partial limb above them and the zero limbs
2061/// through [`limb`].
2062///
2063/// # Safety
2064///
2065/// The operand's vector must be valid for reads, and `out` for writing `to - from` limbs.
2066#[inline(always)]
2067unsafe fn shifted_limbs(x: Operand, from: usize, to: usize, s: u32, out: *mut u64) {
2068    let above = |v: u64| (v >> 1) >> (63 - s);
2069    let full = (x.significant / 8).clamp(from, to);
2070    // SAFETY: as the caller guarantees; the limbs below `full` are whole limbs of the operand.
2071    unsafe {
2072        let mut below = if from > 0 { limb(x, from - 1) } else { 0 };
2073        let end = x.ptr.add(x.len);
2074        if x.big_endian {
2075            for i in from..full {
2076                let v = u64::from_be_bytes(read(end.sub(8 * i + 8)));
2077                *out.add(i - from) = (v << s) | above(below);
2078                below = v;
2079            }
2080        } else {
2081            for i in from..full {
2082                let v = u64::from_le_bytes(read(x.ptr.add(8 * i)));
2083                *out.add(i - from) = (v << s) | above(below);
2084                below = v;
2085            }
2086        }
2087        for i in full..to {
2088            let v = limb(x, i);
2089            *out.add(i - from) = (v << s) | above(below);
2090            below = v;
2091        }
2092    }
2093}
2094
2095/// Reads the significant bytes of the operand `x` into `x.significant.div_ceil(8)` limbs at `out`,
2096/// the least significant first, as the multiplication's `to_limbs` does, shifted left by `s` bits
2097/// on the way, `s < 64`; returns the bits shifted out of the top limb.
2098///
2099/// # Safety
2100///
2101/// The operand's vector must be valid for reads, and `out` for writing its limbs.
2102#[inline(always)]
2103unsafe fn to_limbs_shifted(x: Operand, out: *mut u64, s: u32) -> u64 {
2104    let l = x.significant;
2105    let (full, rem) = (l / 8, l % 8);
2106    // The bits of `v` above `64 - s`, `v >> (64 - s)`, and none for `s = 0`, with shifts below 64.
2107    let above = |v: u64| (v >> 1) >> (63 - s);
2108    let mut below = 0;
2109    // SAFETY: every read lies inside the significant bytes: big-endian the last `l` of the
2110    // vector, little-endian the first `l`.
2111    unsafe {
2112        let end = x.ptr.add(x.len);
2113        for i in 0..full {
2114            let v = if x.big_endian {
2115                u64::from_be_bytes(read(end.sub(8 * i + 8)))
2116            } else {
2117                u64::from_le_bytes(read(x.ptr.add(8 * i)))
2118            };
2119            *out.add(i) = (v << s) | above(below);
2120            below = v;
2121        }
2122        if rem > 0 {
2123            // The `rem` bytes above the whole limbs: from 8 bytes up, the eight that end at the
2124            // top, shifted down to them; below, as the addition reads a short magnitude.
2125            let v = if l >= 8 {
2126                let v = if x.big_endian {
2127                    u64::from_be_bytes(read(end.sub(l)))
2128                } else {
2129                    u64::from_le_bytes(read(x.ptr.add(l - 8)))
2130                };
2131                v >> (8 * (8 - rem))
2132            } else if x.big_endian {
2133                read_small(
2134                    core::slice::from_raw_parts(end.sub(l), rem),
2135                    ByteOrder::BigEndian,
2136                ) as u64
2137            } else {
2138                read_small(
2139                    core::slice::from_raw_parts(x.ptr, rem),
2140                    ByteOrder::LittleEndian,
2141                ) as u64
2142            };
2143            *out.add(full) = (v << s) | above(below);
2144            below = v;
2145        }
2146    }
2147    above(below)
2148}
2149
2150/// The `n` limbs at `r` as a result to write: their length in the shortest form, and the sign
2151/// `negative`, which zero does not keep.
2152///
2153/// # Safety
2154///
2155/// The limbs must be valid for reads.
2156#[inline(always)]
2157unsafe fn result(r: *const u64, n: usize, negative: bool) -> Product {
2158    // SAFETY: as the caller guarantees.
2159    unsafe {
2160        let mut top = n;
2161        while top > 0 && *r.add(top - 1) == 0 {
2162            top -= 1;
2163        }
2164        if top == 0 {
2165            return Product {
2166                r: ptr::null(),
2167                len: 1,
2168                negative: false,
2169            };
2170        }
2171        let len = 8 * top - (*r.add(top - 1)).leading_zeros() as usize / 8;
2172        Product { r, len, negative }
2173    }
2174}