Skip to main content

malachite_nz/natural/arithmetic/
mod_op.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5//      `mpn_dcpi1_div_qr`, `mpn_dcpi1_div_qr_n`, `mpn_mu_div_qr`, `mpn_mu_div_qr2`,
6//      `mpn_preinv_mu_div_qr`, and `mpn_sbpi1_div_qr` contributed to the GNU project by Torbjörn
7//      Granlund.
8//
9//      `mpn_mod_1s_2p_cps`, `mpn_mod_1s_2p`, `mpn_mod_1s_4p_cps`, and `mpn_mod_1s_4p` contributed
10//      to the GNU project by Torbjörn Granlund. Based on a suggestion by Peter L. Montgomery.
11//
12//      `mpn_div_qr_1` contributed to the GNU project by Niels Möller and Torbjörn Granlund.
13//
14//      `mpn_div_qr_1n_pi1` contributed to the GNU project by Niels Möller.
15//
16//      Copyright © 1991, 1993-1996, 1997, 1998-2002, 2003, 2005-2010, 2012, 2013, 2015 Free
17//      Software Foundation, Inc.
18//
19// This file is part of Malachite.
20//
21// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
22// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
23// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
24
25use crate::natural::InnerNatural::{Large, Small};
26use crate::natural::Natural;
27use crate::natural::arithmetic::add::{
28    limbs_add_limb_to_out, limbs_add_same_length_to_out, limbs_slice_add_same_length_in_place_left,
29};
30use crate::natural::arithmetic::div_mod::{
31    MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD, MUPI_DIV_QR_THRESHOLD, limbs_div_barrett_large_product,
32    limbs_div_mod_balanced, limbs_div_mod_barrett_helper, limbs_div_mod_barrett_is_len,
33    limbs_div_mod_barrett_scratch_len, limbs_div_mod_by_two_limb_normalized,
34    limbs_div_mod_divide_and_conquer_helper, limbs_div_mod_schoolbook,
35    limbs_div_mod_three_limb_by_two_limb, limbs_invert_approx, limbs_invert_limb,
36    limbs_two_limb_inverse_helper,
37};
38use crate::natural::arithmetic::mul::mul_mod::limbs_mul_mod_base_pow_n_minus_1_next_size;
39use crate::natural::arithmetic::mul::{
40    limbs_mul_greater_to_out, limbs_mul_greater_to_out_scratch_len, limbs_mul_same_length_to_out,
41    limbs_mul_same_length_to_out_scratch_len, limbs_mul_to_out, limbs_mul_to_out_scratch_len,
42};
43use crate::natural::arithmetic::shl::limbs_shl_to_out;
44use crate::natural::arithmetic::shr::{limbs_shr_to_out, limbs_slice_shr_in_place};
45use crate::natural::arithmetic::sub::{
46    limbs_sub_limb_in_place, limbs_sub_same_length_in_place_left,
47    limbs_sub_same_length_in_place_right, limbs_sub_same_length_to_out,
48    limbs_sub_same_length_with_borrow_in_in_place_left,
49    limbs_sub_same_length_with_borrow_in_in_place_right,
50};
51use crate::natural::arithmetic::sub_mul::limbs_sub_mul_limb_same_length_in_place_left;
52use crate::natural::comparison::cmp::limbs_cmp_same_length;
53use crate::platform::{
54    DC_DIV_QR_THRESHOLD, DoubleLimb, Limb, MOD_1_1_TO_MOD_1_2_THRESHOLD, MOD_1_1P_METHOD,
55    MOD_1_2_TO_MOD_1_4_THRESHOLD, MOD_1_NORM_THRESHOLD, MOD_1_UNNORM_THRESHOLD,
56    MOD_1N_TO_MOD_1_1_THRESHOLD, MOD_1U_TO_MOD_1_1_THRESHOLD, MU_DIV_QR_SKEW_THRESHOLD,
57    MU_DIV_QR_THRESHOLD,
58};
59use alloc::vec::Vec;
60use core::cmp::Ordering::*;
61use core::mem::swap;
62use core::ops::{Rem, RemAssign};
63use malachite_base::num::arithmetic::traits::{
64    Mod, ModAssign, ModPowerOf2, NegMod, NegModAssign, Parity, WrappingAddAssign, WrappingSubAssign,
65};
66use malachite_base::num::basic::integers::PrimitiveInt;
67use malachite_base::num::basic::traits::{One, Zero};
68use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
69use malachite_base::num::conversion::traits::{HasHalf, JoinHalves, SplitInHalf};
70use malachite_base::num::logic::traits::LeadingZeros;
71use malachite_base::slices::{slice_move_left, slice_set_zero};
72
73// # Worst-case complexity
74// Constant time and additional memory.
75//
76// This is equivalent to `udiv_qrnnd_preinv` from `gmp-impl.h`, GMP 6.2.1, but not computing the
77// quotient.
78pub_test! {mod_by_preinversion<
79    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + SplitInHalf + JoinHalves<Half=T>,
80    T: PrimitiveUnsigned,
81>(
82    n_high: T,
83    n_low: T,
84    d: T,
85    d_inv: T,
86) -> T {
87    let (q_high, q_low) = (DT::from(n_high) * DT::from(d_inv))
88        .wrapping_add(DT::join_halves(n_high.wrapping_add(T::ONE), n_low))
89        .split_in_half();
90    let mut r = n_low.wrapping_sub(q_high.wrapping_mul(d));
91    if r > q_low {
92        r.wrapping_add_assign(d);
93    }
94    if r >= d {
95        r -= d;
96    }
97    r
98}}
99
100// Interpreting a slice of `Limb`s as the limbs (in ascending order) of a `Natural`, returns the
101// remainder when the `Natural` is divided by a `Limb`.
102//
103// The divisor limb cannot be zero and the input limb slice must have at least two elements.
104//
105// # Worst-case complexity
106// $T(n) = O(n)$
107//
108// $M(n) = O(1)$
109//
110// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
111//
112// # Panics
113// Panics if the length of `ns` is less than 2 or if `d` is zero.
114#[cfg(feature = "32_bit_limbs")]
115#[cfg(feature = "test_build")]
116#[inline]
117pub fn limbs_mod_limb<
118    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + SplitInHalf + JoinHalves<Half = T>,
119    T: PrimitiveUnsigned,
120>(
121    ns: &[T],
122    d: T,
123) -> T {
124    limbs_mod_limb_alt_2::<DT, T>(ns, d)
125}
126#[cfg(feature = "32_bit_limbs")]
127#[cfg(not(feature = "test_build"))]
128#[inline]
129pub(crate) fn limbs_mod_limb<
130    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + SplitInHalf + JoinHalves<Half = T>,
131    T: PrimitiveUnsigned,
132>(
133    ns: &[T],
134    d: T,
135) -> T {
136    limbs_mod_limb_alt_2::<DT, T>(ns, d)
137}
138#[cfg(not(feature = "32_bit_limbs"))]
139#[cfg(feature = "test_build")]
140#[inline]
141pub fn limbs_mod_limb<
142    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + SplitInHalf + JoinHalves<Half = T>,
143    T: PrimitiveUnsigned,
144>(
145    ns: &[Limb],
146    d: Limb,
147) -> Limb {
148    limbs_mod_limb_alt_1::<DoubleLimb, Limb>(ns, d)
149}
150#[cfg(not(feature = "32_bit_limbs"))]
151#[cfg(not(feature = "test_build"))]
152pub(crate) fn limbs_mod_limb<
153    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + SplitInHalf + JoinHalves<Half = T>,
154    T: PrimitiveUnsigned,
155>(
156    ns: &[T],
157    d: T,
158) -> T {
159    limbs_mod_limb_alt_1::<DT, T>(ns, d)
160}
161
162// Computes the remainder of `[n_2, n_1, n_0]` / `[d_1, d_0]`. Requires the highest bit of `d_1` to
163// be set, and `[n_2, n_1]` < `[d_1, d_0]`. `d_inv` is the inverse of `[d_1, d_0]` computed by
164// `limbs_two_limb_inverse_helper`.
165//
166// # Worst-case complexity
167// Constant time and additional memory.
168//
169// This is equivalent to `udiv_qr_3by2` from `gmp-impl.h`, GMP 6.2.1, returning only the remainder.
170pub_test! {limbs_mod_three_limb_by_two_limb(
171    n_2: Limb,
172    n_1: Limb,
173    n_0: Limb,
174    d_1: Limb,
175    d_0: Limb,
176    d_inv: Limb,
177) -> DoubleLimb {
178    let (q, q_lo) = (DoubleLimb::from(n_2) * DoubleLimb::from(d_inv))
179        .wrapping_add(DoubleLimb::join_halves(n_2, n_1))
180        .split_in_half();
181    let d = DoubleLimb::join_halves(d_1, d_0);
182    // Compute the two most significant limbs of n - q * d
183    let r = DoubleLimb::join_halves(n_1.wrapping_sub(d_1.wrapping_mul(q)), n_0)
184        .wrapping_sub(d)
185        .wrapping_sub(DoubleLimb::from(d_0) * DoubleLimb::from(q));
186    // Conditionally adjust the remainder
187    if r.upper_half() >= q_lo {
188        let (r_plus_d, overflow) = r.overflowing_add(d);
189        if overflow {
190            return r_plus_d;
191        }
192    } else if r >= d {
193        return r.wrapping_sub(d);
194    }
195    r
196}}
197
198// Divides `ns` by `ds`, returning the limbs of the remainder. `ds` must have length 2, `ns` must
199// have length at least 2, and the most significant bit of `ds[1]` must be set.
200//
201// # Worst-case complexity
202// $T(n) = O(n)$
203//
204// $M(n) = O(1)$
205//
206// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
207//
208// # Panics
209// Panics if `ds` does not have length 2, `ns` has length less than 2, `qs` has length less than
210// `ns.len() - 2`, or `ds[1]` does not have its highest bit set.
211//
212// This is equivalent to `mpn_divrem_2` from `mpn/generic/divrem_2.c`, GMP 6.2.1, returning the two
213// limbs of the remainder.
214pub_test! {limbs_mod_by_two_limb_normalized(ns: &[Limb], ds: &[Limb]) -> (Limb, Limb) {
215    assert_eq!(ds.len(), 2);
216    let n_len = ns.len();
217    assert!(n_len >= 2);
218    let n_limit = n_len - 2;
219    assert!(ds[1].get_highest_bit());
220    let d_1 = ds[1];
221    let d_0 = ds[0];
222    let d = DoubleLimb::join_halves(d_1, d_0);
223    let mut r = DoubleLimb::join_halves(ns[n_limit + 1], ns[n_limit]);
224    if r >= d {
225        r.wrapping_sub_assign(d);
226    }
227    let (mut r_1, mut r_0) = r.split_in_half();
228    let d_inv = limbs_two_limb_inverse_helper(d_1, d_0);
229    for &n in ns[..n_limit].iter().rev() {
230        (r_1, r_0) = limbs_mod_three_limb_by_two_limb(r_1, r_0, n, d_1, d_0, d_inv).split_in_half();
231    }
232    (r_0, r_1)
233}}
234
235// Divides `ns` by `ds` and writes the `ds.len()` limbs of the remainder to `ns`. `ds` must have
236// length greater than 2, `ns` must be at least as long as `ds`, and the most significant bit of
237// `ds` must be set. `d_inv` should be the result of `limbs_two_limb_inverse_helper` applied to the
238// two highest limbs of the denominator.
239//
240// # Worst-case complexity
241// $T(n, d) = O(d(n - d + 1)) = O(n^2)$
242//
243// $M(n) = O(1)$
244//
245// where $T$ is time, $M$ is additional memory, $n$ is `ns.len()`, and $d$ is `ds.len()`.
246//
247// # Panics
248// Panics if `ds` has length smaller than 3, `ns` is shorter than `ds`, or the last limb of `ds`
249// does not have its highest bit set.
250//
251// This is equivalent to `mpn_sbpi1_div_qr` from `mpn/generic/sbpi1_div_qr.c`, GMP 6.2.1, where only
252// the remainder is calculated.
253pub_test! {limbs_mod_schoolbook(ns: &mut [Limb], ds: &[Limb], d_inv: Limb) {
254    let d_len = ds.len();
255    assert!(d_len > 2);
256    let n_len = ns.len();
257    assert!(n_len >= d_len);
258    let (d_1, ds_init) = ds.split_last().unwrap();
259    let d_1 = *d_1;
260    assert!(d_1.get_highest_bit());
261    let (d_0, ds_init_init) = ds_init.split_last().unwrap();
262    let d_0 = *d_0;
263    let ns_hi = &mut ns[n_len - d_len..];
264    if limbs_cmp_same_length(ns_hi, ds) >= Equal {
265        limbs_sub_same_length_in_place_left(ns_hi, ds);
266    }
267    let mut n_1 = ns[n_len - 1];
268    for i in (d_len..n_len).rev() {
269        let j = i - d_len;
270        if n_1 == d_1 && ns[i - 1] == d_0 {
271            limbs_sub_mul_limb_same_length_in_place_left(&mut ns[j..i], ds, Limb::MAX);
272            n_1 = ns[i - 1]; // update n_1, last loop's value will now be invalid
273        } else {
274            let (ns_lo, ns_hi) = ns.split_at_mut(i - 2);
275            let (q, n) =
276                limbs_div_mod_three_limb_by_two_limb(n_1, ns_hi[1], ns_hi[0], d_1, d_0, d_inv);
277            let mut n_0;
278            (n_1, n_0) = n.split_in_half();
279            let local_carry_1 =
280                limbs_sub_mul_limb_same_length_in_place_left(&mut ns_lo[j..], ds_init_init, q);
281            let local_carry_2 = n_0 < local_carry_1;
282            n_0.wrapping_sub_assign(local_carry_1);
283            let carry = local_carry_2 && n_1 == 0;
284            if local_carry_2 {
285                n_1.wrapping_sub_assign(1);
286            }
287            ns_hi[0] = n_0;
288            if carry {
289                n_1.wrapping_add_assign(d_1);
290                if limbs_slice_add_same_length_in_place_left(&mut ns[j..i - 1], ds_init) {
291                    n_1.wrapping_add_assign(1);
292                }
293            }
294        }
295    }
296    ns[d_len - 1] = n_1;
297}}
298
299// `qs` is just used as scratch space.
300//
301// # Worst-case complexity
302// $T(n) = O(n (\log n)^2 \log\log n)$
303//
304// $M(n) = O(n(\log n)^2)$
305//
306// where $T$ is time, $M$ is additional memory, and $n$ is `ds.len()`.
307//
308// This is equivalent to `mpn_dcpi1_div_qr_n` from `mpn/generic/dcpi1_div_qr.c`, GMP 6.2.1, where
309// only the remainder is calculated.
310fn limbs_mod_divide_and_conquer_helper(
311    qs: &mut [Limb],
312    ns: &mut [Limb],
313    ds: &[Limb],
314    d_inv: Limb,
315    scratch: &mut [Limb],
316) {
317    let n = ds.len();
318    let lo = n >> 1; // floor(n / 2)
319    let hi = n - lo; // ceil(n / 2)
320    let qs_hi = &mut qs[lo..];
321    let (ds_lo, ds_hi) = ds.split_at(lo);
322    let highest_q = if hi < DC_DIV_QR_THRESHOLD {
323        limbs_div_mod_schoolbook(qs_hi, &mut ns[lo << 1..n << 1], ds_hi, d_inv)
324    } else {
325        limbs_div_mod_divide_and_conquer_helper(qs_hi, &mut ns[lo << 1..], ds_hi, d_inv, scratch)
326    };
327    let qs_hi = &mut qs_hi[..hi];
328    let mut mul_scratch = vec![0; limbs_mul_greater_to_out_scratch_len(qs_hi.len(), ds_lo.len())];
329    limbs_mul_greater_to_out(scratch, qs_hi, ds_lo, &mut mul_scratch);
330    let ns_lo = &mut ns[..n + lo];
331    let mut carry = Limb::from(limbs_sub_same_length_in_place_left(
332        &mut ns_lo[lo..],
333        &scratch[..n],
334    ));
335    if highest_q && limbs_sub_same_length_in_place_left(&mut ns_lo[n..], ds_lo) {
336        carry += 1;
337    }
338    while carry != 0 {
339        limbs_sub_limb_in_place(qs_hi, 1);
340        if limbs_slice_add_same_length_in_place_left(&mut ns_lo[lo..], ds) {
341            carry -= 1;
342        }
343    }
344    let (ds_lo, ds_hi) = ds.split_at(hi);
345    let q_lo = if lo < DC_DIV_QR_THRESHOLD {
346        limbs_div_mod_schoolbook(qs, &mut ns[hi..n + lo], ds_hi, d_inv)
347    } else {
348        limbs_div_mod_divide_and_conquer_helper(qs, &mut ns[hi..], ds_hi, d_inv, scratch)
349    };
350    let qs_lo = &mut qs[..lo];
351    let ns_lo = &mut ns[..n];
352    let mut mul_scratch = vec![0; limbs_mul_greater_to_out_scratch_len(ds_lo.len(), lo)];
353    limbs_mul_greater_to_out(scratch, ds_lo, qs_lo, &mut mul_scratch);
354    let mut carry = Limb::from(limbs_sub_same_length_in_place_left(ns_lo, &scratch[..n]));
355    if q_lo && limbs_sub_same_length_in_place_left(&mut ns_lo[lo..], ds_lo) {
356        carry += 1;
357    }
358    while carry != 0 {
359        if limbs_slice_add_same_length_in_place_left(ns_lo, ds) {
360            carry -= 1;
361        }
362    }
363}
364
365// `qs` is just used as scratch space.
366//
367// # Worst-case complexity
368// $T(n) = O(n (\log n)^2 \log\log n)$
369//
370// $M(n) = O(n(\log n)^2)$
371//
372// where $T$ is time, $M$ is additional memory, and $n$ is `ds.len()`.
373//
374// # Panics
375// Panics if `ds` has length smaller than 6, `ns.len()` is less than `ds.len()` + 3, `qs` has length
376// less than `ns.len()` - `ds.len()`, or the last limb of `ds` does not have its highest bit set.
377//
378// This is equivalent to `mpn_dcpi1_div_qr` from `mpn/generic/dcpi1_div_qr.c`, GMP 6.2.1, where only
379// the remainder is calculated.
380pub_test! {limbs_mod_divide_and_conquer(
381    qs: &mut [Limb],
382    ns: &mut [Limb],
383    ds: &[Limb],
384    d_inv: Limb
385) {
386    let n_len = ns.len();
387    let d_len = ds.len();
388    assert!(d_len >= 6); // to adhere to limbs_div_mod_schoolbook's limits
389    assert!(n_len >= d_len + 3); // to adhere to limbs_div_mod_schoolbook's limits
390    let a = d_len - 1;
391    let d_1 = ds[a];
392    let b = d_len - 2;
393    assert!(d_1.get_highest_bit());
394    let mut scratch = vec![0; d_len];
395    let q_len = n_len - d_len;
396    if q_len > d_len {
397        let q_len_mod_d_len = {
398            let mut m = q_len % d_len;
399            if m == 0 {
400                m = d_len;
401            }
402            m
403        };
404        // Perform the typically smaller block first. point at low limb of next quotient block
405        let qs_block = &mut qs[q_len - q_len_mod_d_len..q_len];
406        if q_len_mod_d_len == 1 {
407            // Handle highest_q up front, for simplicity.
408            let ns = &mut ns[q_len - 1..];
409            let ns_tail = &mut ns[1..];
410            if limbs_cmp_same_length(ns_tail, ds) >= Equal {
411                assert!(!limbs_sub_same_length_in_place_left(ns_tail, ds));
412            }
413            // A single iteration of schoolbook: One 3/2 division, followed by the bignum update and
414            // adjustment.
415            let (last_n, ns) = ns.split_last_mut().unwrap();
416            let n_2 = *last_n;
417            let mut n_1 = ns[a];
418            let mut n_0 = ns[b];
419            let d_0 = ds[b];
420            assert!(n_2 < d_1 || n_2 == d_1 && n_1 <= d_0);
421            let mut q;
422            if n_2 == d_1 && n_1 == d_0 {
423                q = Limb::MAX;
424                assert_eq!(limbs_sub_mul_limb_same_length_in_place_left(ns, ds, q), n_2);
425            } else {
426                let n;
427                (q, n) = limbs_div_mod_three_limb_by_two_limb(n_2, n_1, n_0, d_1, d_0, d_inv);
428                (n_1, n_0) = n.split_in_half();
429                // d_len > 2 because of precondition. No need to check
430                let local_carry_1 =
431                    limbs_sub_mul_limb_same_length_in_place_left(&mut ns[..b], &ds[..b], q);
432                let local_carry_2 = n_0 < local_carry_1;
433                n_0.wrapping_sub_assign(local_carry_1);
434                let carry = local_carry_2 && n_1 == 0;
435                if local_carry_2 {
436                    n_1.wrapping_sub_assign(1);
437                }
438                ns[b] = n_0;
439                let (ns_last, ns_init) = ns.split_last_mut().unwrap();
440                if carry {
441                    n_1.wrapping_add_assign(d_1);
442                    if limbs_slice_add_same_length_in_place_left(ns_init, &ds[..a]) {
443                        n_1.wrapping_add_assign(1);
444                    }
445                    q.wrapping_sub_assign(1);
446                }
447                *ns_last = n_1;
448            }
449            qs_block[0] = q;
450        } else {
451            // Do a 2 * q_len_mod_d_len / q_len_mod_d_len division
452            let (ds_lo, ds_hi) = ds.split_at(d_len - q_len_mod_d_len);
453            let highest_q = {
454                let ns = &mut ns[n_len - (q_len_mod_d_len << 1)..];
455                if q_len_mod_d_len == 2 {
456                    limbs_div_mod_by_two_limb_normalized(qs_block, ns, ds_hi)
457                } else if q_len_mod_d_len < DC_DIV_QR_THRESHOLD {
458                    limbs_div_mod_schoolbook(qs_block, ns, ds_hi, d_inv)
459                } else {
460                    limbs_div_mod_divide_and_conquer_helper(
461                        qs_block,
462                        ns,
463                        ds_hi,
464                        d_inv,
465                        &mut scratch,
466                    )
467                }
468            };
469            if q_len_mod_d_len != d_len {
470                let mut mul_scratch =
471                    vec![0; limbs_mul_to_out_scratch_len(qs_block.len(), ds_lo.len())];
472                limbs_mul_to_out(&mut scratch, qs_block, ds_lo, &mut mul_scratch);
473                let ns = &mut ns[q_len - q_len_mod_d_len..n_len - q_len_mod_d_len];
474                let mut carry = Limb::from(limbs_sub_same_length_in_place_left(ns, &scratch));
475                if highest_q
476                    && limbs_sub_same_length_in_place_left(&mut ns[q_len_mod_d_len..], ds_lo)
477                {
478                    carry += 1;
479                }
480                while carry != 0 {
481                    limbs_sub_limb_in_place(qs_block, 1);
482                    if limbs_slice_add_same_length_in_place_left(ns, ds) {
483                        carry -= 1;
484                    }
485                }
486            }
487        }
488        // offset is a multiple of d_len
489        let mut offset = n_len.checked_sub(d_len + q_len_mod_d_len).unwrap();
490        while offset != 0 {
491            offset -= d_len;
492            limbs_mod_divide_and_conquer_helper(
493                &mut qs[offset..],
494                &mut ns[offset..],
495                ds,
496                d_inv,
497                &mut scratch,
498            );
499        }
500    } else {
501        let m = d_len - q_len;
502        let (ds_lo, ds_hi) = ds.split_at(m);
503        let highest_q = if q_len < DC_DIV_QR_THRESHOLD {
504            limbs_div_mod_schoolbook(qs, &mut ns[m..], ds_hi, d_inv)
505        } else {
506            limbs_div_mod_divide_and_conquer_helper(qs, &mut ns[m..], ds_hi, d_inv, &mut scratch)
507        };
508        if m != 0 {
509            let qs = &mut qs[..q_len];
510            let ns = &mut ns[..d_len];
511            let mut mul_scratch = vec![0; limbs_mul_to_out_scratch_len(q_len, ds_lo.len())];
512            limbs_mul_to_out(&mut scratch, qs, ds_lo, &mut mul_scratch);
513            let mut carry = Limb::from(limbs_sub_same_length_in_place_left(ns, &scratch));
514            if highest_q && limbs_sub_same_length_in_place_left(&mut ns[q_len..], ds_lo) {
515                carry += 1;
516            }
517            while carry != 0 {
518                if limbs_slice_add_same_length_in_place_left(ns, ds) {
519                    carry -= 1;
520                }
521            }
522        }
523    }
524}}
525
526// `qs` is just used as scratch space.
527//
528// # Worst-case complexity
529// $T(n, d) = O(n \log d \log\log d)$
530//
531// $M(n) = O(d(\log d)^2)$
532//
533// where $T$ is time, $M$ is additional memory, n$ is `ns.len()`, and $d$ is `ds.len()`.
534//
535// This is equivalent to `mpn_preinv_mu_div_qr` from `mpn/generic/mu_div_qr.c`, GMP 6.2.1, where
536// only the remainder is calculated.
537fn limbs_mod_barrett_preinverted(
538    qs: &mut [Limb],
539    rs: &mut [Limb],
540    ns: &[Limb],
541    ds: &[Limb],
542    mut is: &[Limb],
543    scratch: &mut [Limb],
544) {
545    let n_len = ns.len();
546    let d_len = ds.len();
547    assert_eq!(rs.len(), d_len);
548    let mut i_len = is.len();
549    let q_len = n_len - d_len;
550    let qs = &mut qs[..q_len];
551    let (ns_lo, ns_hi) = ns.split_at(q_len);
552    if limbs_cmp_same_length(ns_hi, ds) >= Equal {
553        limbs_sub_same_length_to_out(rs, ns_hi, ds);
554    } else {
555        rs.copy_from_slice(ns_hi);
556    }
557    let scratch_len = if i_len < MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD {
558        0
559    } else {
560        limbs_mul_mod_base_pow_n_minus_1_next_size(d_len + 1)
561    };
562    let mut n = d_len - i_len;
563    for (ns, qs) in ns_lo.rchunks(i_len).zip(qs.rchunks_mut(i_len)) {
564        let chunk_len = ns.len();
565        if i_len != chunk_len {
566            // last iteration
567            is = &is[i_len - chunk_len..];
568            i_len = chunk_len;
569            n = d_len - i_len;
570        }
571        let (rs_lo, rs_hi) = rs.split_at_mut(n);
572        // Compute the next block of quotient limbs by multiplying the inverse by the upper part of
573        // the partial remainder.
574        let mut mul_scratch = vec![0; limbs_mul_same_length_to_out_scratch_len(is.len())];
575        limbs_mul_same_length_to_out(scratch, rs_hi, is, &mut mul_scratch);
576        // The inverse's most significant bit is implicit.
577        assert!(!limbs_add_same_length_to_out(
578            qs,
579            &scratch[i_len..i_len << 1],
580            rs_hi,
581        ));
582        // Compute the product of the quotient block and the divisor, to be subtracted from the
583        // partial remainder combined with new limbs from the dividend. We only really need the low
584        // d_len + 1 limbs.
585        if i_len < MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD {
586            let mut mul_scratch = vec![0; limbs_mul_greater_to_out_scratch_len(ds.len(), qs.len())];
587            limbs_mul_greater_to_out(scratch, ds, qs, &mut mul_scratch);
588        } else {
589            limbs_div_barrett_large_product(scratch, ds, qs, rs_hi, scratch_len, i_len);
590        }
591        let mut r = rs_hi[0].wrapping_sub(scratch[d_len]);
592        // Subtract the product from the partial remainder combined with new limbs from the
593        // dividend, generating a new partial remainder.
594        let scratch = &mut scratch[..d_len];
595        let carry = if n == 0 {
596            // Get next i_len limbs from n.
597            limbs_sub_same_length_to_out(rs, ns, scratch)
598        } else {
599            let (scratch_lo, scratch_hi) = scratch.split_at_mut(i_len);
600            // Get next i_len limbs from n.
601            let carry = limbs_sub_same_length_with_borrow_in_in_place_right(
602                rs_lo,
603                scratch_hi,
604                limbs_sub_same_length_in_place_right(ns, scratch_lo),
605            );
606            rs.copy_from_slice(scratch);
607            carry
608        };
609        // Check the remainder.
610        if carry {
611            r.wrapping_sub_assign(1);
612        }
613        while r != 0 {
614            // We loop 0 times with about 69% probability, 1 time with about 31% probability, and 2
615            // times with about 0.6% probability, if the inverse is computed as recommended.
616            if limbs_sub_same_length_in_place_left(rs, ds) {
617                r -= 1;
618            }
619        }
620        if limbs_cmp_same_length(rs, ds) >= Equal {
621            // This is executed with about 76% probability.
622            limbs_sub_same_length_in_place_left(rs, ds);
623        }
624    }
625}
626
627// `qs` is just used as scratch space.
628//
629// # Worst-case complexity
630// $T(n) = O(n \log n \log\log n)$
631//
632// $M(n) = O(n \log n)$
633//
634// where $T$ is time, $M$ is additional memory, and n$ is `ns.len()`.
635//
636// This is equivalent to `mpn_mu_div_qr2` from `mpn/generic/mu_div_qr.c`, GMP 6.2.1, where only the
637// remainder is calculated.
638pub_test! {limbs_mod_barrett_helper(
639    qs: &mut [Limb],
640    rs: &mut [Limb],
641    ns: &[Limb],
642    ds: &[Limb],
643    scratch: &mut [Limb],
644) {
645    let n_len = ns.len();
646    let d_len = ds.len();
647    assert_eq!(rs.len(), d_len);
648    assert!(d_len > 1);
649    assert!(n_len > d_len);
650    let q_len = n_len - d_len;
651    // Compute the inverse size.
652    let i_len = limbs_div_mod_barrett_is_len(q_len, d_len);
653    assert!(i_len <= d_len);
654    let i_len_plus_1 = i_len + 1;
655    let (is, scratch_hi) = scratch.split_at_mut(i_len_plus_1);
656    // compute an approximate inverse on i_len + 1 limbs
657    if d_len == i_len {
658        let (scratch_lo, scratch_hi) = scratch_hi.split_at_mut(i_len_plus_1);
659        let (scratch_first, scratch_lo_tail) = scratch_lo.split_first_mut().unwrap();
660        scratch_lo_tail.copy_from_slice(&ds[..i_len]);
661        *scratch_first = 1;
662        limbs_invert_approx(is, scratch_lo, scratch_hi);
663        slice_move_left(is, 1);
664    } else if limbs_add_limb_to_out(scratch_hi, &ds[d_len - i_len_plus_1..], 1) {
665        slice_set_zero(&mut is[..i_len]);
666    } else {
667        let (scratch_lo, scratch_hi) = scratch_hi.split_at_mut(i_len_plus_1);
668        limbs_invert_approx(is, scratch_lo, scratch_hi);
669        slice_move_left(is, 1);
670    }
671    let (scratch_lo, scratch_hi) = scratch.split_at_mut(i_len);
672    limbs_mod_barrett_preinverted(qs, rs, ns, ds, scratch_lo, scratch_hi);
673}}
674
675// `qs` is just used as scratch space.
676//
677// # Worst-case complexity
678// $T(n) = O(n \log n \log\log n)$
679//
680// $M(n) = O(n \log n)$
681//
682// where $T$ is time, $M$ is additional memory, and n$ is `ns.len()`.
683fn limbs_mod_barrett_large_helper(
684    qs: &mut [Limb],
685    rs: &mut [Limb],
686    ns: &[Limb],
687    ds: &[Limb],
688    scratch: &mut [Limb],
689) {
690    let n_len = ns.len();
691    let d_len = ds.len();
692    let q_len = qs.len();
693    let q_len_plus_one = q_len + 1;
694    let n = n_len - q_len - q_len_plus_one; // 2 * d_len - n_len - 1
695    let (ns_lo, ns_hi) = ns.split_at(n);
696    let (ds_lo, ds_hi) = ds.split_at(d_len - q_len_plus_one);
697    let (rs_lo, rs_hi) = rs.split_at_mut(n);
698    let rs_hi = &mut rs_hi[..q_len_plus_one];
699    let highest_q = limbs_div_mod_barrett_helper(qs, rs_hi, ns_hi, ds_hi, scratch);
700    // Multiply the quotient by the divisor limbs ignored above. The product is d_len - 1 limbs
701    // long.
702    let mut mul_scratch = vec![0; limbs_mul_to_out_scratch_len(ds_lo.len(), qs.len())];
703    limbs_mul_to_out(scratch, ds_lo, qs, &mut mul_scratch);
704    let (scratch_last, scratch_init) = scratch[..d_len].split_last_mut().unwrap();
705    *scratch_last = Limb::from(
706        highest_q && limbs_slice_add_same_length_in_place_left(&mut scratch_init[q_len..], ds_lo),
707    );
708    let (scratch_lo, scratch_hi) = scratch.split_at(n);
709    let scratch_hi = &scratch_hi[..q_len_plus_one];
710    if limbs_sub_same_length_with_borrow_in_in_place_left(
711        rs_hi,
712        scratch_hi,
713        limbs_sub_same_length_to_out(rs_lo, ns_lo, scratch_lo),
714    ) {
715        limbs_slice_add_same_length_in_place_left(&mut rs[..d_len], ds);
716    }
717}
718
719// `qs` is just used as scratch space.
720//
721// `ns` must have length at least 3, `ds` must have length at least 2 and be no longer than `ns`,
722// and the most significant bit of `ds` must be set.
723//
724// # Worst-case complexity
725// $T(n) = O(n \log n \log\log n)$
726//
727// $M(n) = O(n \log n)$
728//
729// where $T$ is time, $M$ is additional memory, and n$ is `ns.len()`.
730//
731// # Panics
732// Panics if `ds` has length smaller than 2, `ns.len()` is less than `ds.len()`, `qs` has length
733// less than `ns.len()` - `ds.len()`, or the last limb of `ds` does not have its highest bit set.
734//
735// This is equivalent to `mpn_mu_div_qr` from `mpn/generic/mu_div_qr.c`, GMP 6.2.1.
736pub_test! {limbs_mod_barrett(
737    qs: &mut [Limb],
738    rs: &mut [Limb],
739    ns: &[Limb],
740    ds: &[Limb],
741    scratch: &mut [Limb],
742) {
743    let n_len = ns.len();
744    let d_len = ds.len();
745    let q_len = n_len - d_len;
746    let qs = &mut qs[..q_len];
747    // Test whether 2 * d_len - n_len > MU_DIV_QR_SKEW_THRESHOLD
748    if d_len <= q_len + MU_DIV_QR_SKEW_THRESHOLD {
749        limbs_mod_barrett_helper(qs, &mut rs[..d_len], ns, ds, scratch);
750    } else {
751        limbs_mod_barrett_large_helper(qs, rs, ns, ds, scratch);
752    }
753}}
754
755/// `ds` must have length 2, `ns` must have length at least 2, and the most-significant limb of `ds`
756/// must be nonzero.
757///
758// # Worst-case complexity
759// $T(n) = O(n)$
760//
761// $M(n) = O(n)$
762//
763// where $T$ is time, $M$ is additional memory, and n$ is `ns.len()`.
764fn limbs_mod_by_two_limb(ns: &[Limb], ds: &[Limb]) -> (Limb, Limb) {
765    let n_len = ns.len();
766    let ds_1 = ds[1];
767    let bits = LeadingZeros::leading_zeros(ds_1);
768    if bits == 0 {
769        limbs_mod_by_two_limb_normalized(ns, ds)
770    } else {
771        let ds_0 = ds[0];
772        let cobits = Limb::WIDTH - bits;
773        let mut ns_shifted = vec![0; n_len + 1];
774        let ns_shifted = &mut ns_shifted;
775        let carry = limbs_shl_to_out(ns_shifted, ns, bits);
776        let ds_shifted = &mut [ds_0 << bits, (ds_1 << bits) | (ds_0 >> cobits)];
777        let (r_0, r_1) = if carry == 0 {
778            limbs_mod_by_two_limb_normalized(&ns_shifted[..n_len], ds_shifted)
779        } else {
780            ns_shifted[n_len] = carry;
781            limbs_mod_by_two_limb_normalized(ns_shifted, ds_shifted)
782        };
783        ((r_0 >> bits) | (r_1 << cobits), r_1 >> bits)
784    }
785}
786
787// # Worst-case complexity
788// Constant time and additional memory.
789fn limbs_mod_dc_condition(n_len: usize, d_len: usize) -> bool {
790    let n_64 = n_len as f64;
791    let d_64 = d_len as f64;
792    d_len < MUPI_DIV_QR_THRESHOLD
793        || n_len < MU_DIV_QR_THRESHOLD << 1
794        || fma!(
795            ((MU_DIV_QR_THRESHOLD - MUPI_DIV_QR_THRESHOLD) << 1) as f64,
796            d_64,
797            MUPI_DIV_QR_THRESHOLD as f64 * n_64
798        ) > d_64 * n_64
799}
800
801// This function is optimized for the case when the numerator has at least twice the length of the
802// denominator.
803//
804// `ds` must have length at least 3, `ns` must be at least as long as `ds`, `rs` must have the same
805// length as `ds`, and the most-significant limb of `ds` must be nonzero.
806//
807// # Worst-case complexity
808// $T(n) = O(n \log n \log\log n)$
809//
810// $M(n) = O(n \log n)$
811//
812// where $T$ is time, $M$ is additional memory, and n$ is `ns.len()`.
813fn limbs_mod_unbalanced(rs: &mut [Limb], ns: &[Limb], ds: &[Limb], adjusted_n_len: usize) {
814    let mut n_len = ns.len();
815    let d_len = ds.len();
816    let mut ds_shifted_vec;
817    let ds_shifted: &[Limb];
818    let mut ns_shifted_vec = vec![0; n_len + 1];
819    let ns_shifted = &mut ns_shifted_vec;
820    let bits = LeadingZeros::leading_zeros(*ds.last().unwrap());
821    if bits == 0 {
822        ds_shifted = ds;
823        ns_shifted[..n_len].copy_from_slice(ns);
824    } else {
825        // normalize divisor
826        ds_shifted_vec = vec![0; d_len];
827        limbs_shl_to_out(&mut ds_shifted_vec, ds, bits);
828        ds_shifted = &ds_shifted_vec;
829        let (ns_shifted_last, ns_shifted_init) = ns_shifted.split_last_mut().unwrap();
830        *ns_shifted_last = limbs_shl_to_out(ns_shifted_init, ns, bits);
831    }
832    n_len = adjusted_n_len;
833    let d_inv = limbs_two_limb_inverse_helper(ds_shifted[d_len - 1], ds_shifted[d_len - 2]);
834    let ns_shifted = &mut ns_shifted[..n_len];
835    if d_len < DC_DIV_QR_THRESHOLD {
836        limbs_mod_schoolbook(ns_shifted, ds_shifted, d_inv);
837        let ns_shifted = &ns_shifted[..d_len];
838        if bits == 0 {
839            rs.copy_from_slice(ns_shifted);
840        } else {
841            limbs_shr_to_out(rs, ns_shifted, bits);
842        }
843    } else if limbs_mod_dc_condition(n_len, d_len) {
844        let mut qs = vec![0; n_len - d_len];
845        limbs_mod_divide_and_conquer(&mut qs, ns_shifted, ds_shifted, d_inv);
846        let ns_shifted = &ns_shifted[..d_len];
847        if bits == 0 {
848            rs.copy_from_slice(ns_shifted);
849        } else {
850            limbs_shr_to_out(rs, ns_shifted, bits);
851        }
852    } else {
853        let scratch_len = limbs_div_mod_barrett_scratch_len(n_len, d_len);
854        let mut qs = vec![0; n_len - d_len];
855        let mut scratch = vec![0; scratch_len];
856        limbs_mod_barrett(&mut qs, rs, ns_shifted, ds_shifted, &mut scratch);
857        if bits != 0 {
858            limbs_slice_shr_in_place(rs, bits);
859        }
860    }
861}
862
863// Interpreting two slices of `Limb`s, `ns` and `ds`, as the limbs (in ascending order) of two
864// `Natural`s, divides them, returning the remainder. The remainder has `ds.len()` limbs.
865//
866// `ns` must be at least as long as `ds` and `ds` must have length at least 2 and its most
867// significant limb must be greater than zero.
868//
869// # Worst-case complexity
870// $T(n) = O(n \log n \log\log n)$
871//
872// $M(n) = O(n \log n)$
873//
874// where $T$ is time, $M$ is additional memory, and n$ is `ns.len()`.
875//
876// # Panics
877// Panics if `ns` is shorter than `ds`, `ds` has length less than 2, or the most-significant limb of
878// `ds` is zero.
879//
880// This is equivalent to `mpn_tdiv_qr` from `mpn/generic/tdiv_qr.c`, GMP 6.2.1, where `qp` is not
881// calculated and `rp` is returned.
882pub_test! {limbs_mod(ns: &[Limb], ds: &[Limb]) -> Vec<Limb> {
883    let mut rs = vec![0; ds.len()];
884    limbs_mod_to_out(&mut rs, ns, ds);
885    rs
886}}
887
888// Interpreting two slices of `Limb`s, `ns` and `ds`, as the limbs (in ascending order) of two
889// `Natural`s, divides them, writing the `ds.len()` limbs of the remainder to `rs`.
890//
891// `ns` must be at least as long as `ds`, `rs` must be at least as long as `ds`, and `ds` must have
892// length at least 2 and its most significant limb must be greater than zero.
893//
894// # Worst-case complexity
895// $T(n) = O(n \log n \log\log n)$
896//
897// $M(n) = O(n \log n)$
898//
899// where $T$ is time, $M$ is additional memory, and n$ is `ns.len()`.
900//
901// # Panics
902// Panics if `rs` is too short, `ns` is shorter than `ds`, `ds` has length less than 2, or the
903// most-significant limb of `ds` is zero.
904//
905// This is equivalent to `mpn_tdiv_qr` from `mpn/generic/tdiv_qr.c`, GMP 6.2.1, where `qp` is not
906// calculated.
907pub_crate_test! {limbs_mod_to_out(rs: &mut [Limb], ns: &[Limb], ds: &[Limb]) {
908    let n_len = ns.len();
909    let d_len = ds.len();
910    assert!(n_len >= d_len);
911    let rs = &mut rs[..d_len];
912    let ds_last = *ds.last().unwrap();
913    assert!(d_len > 1 && ds_last != 0);
914    if d_len == 2 {
915        (rs[0], rs[1]) = limbs_mod_by_two_limb(ns, ds);
916    } else {
917        // conservative tests for quotient size
918        let adjust = ns[n_len - 1] >= ds_last;
919        let adjusted_n_len = if adjust { n_len + 1 } else { n_len };
920        if adjusted_n_len < d_len << 1 {
921            let mut qs = vec![0; n_len - d_len + 1];
922            limbs_div_mod_balanced(&mut qs, rs, ns, ds, adjust);
923        } else {
924            limbs_mod_unbalanced(rs, ns, ds, adjusted_n_len);
925        }
926    }
927}}
928
929// # Worst-case complexity
930// $T(n) = O(n)$
931//
932// $M(n) = O(1)$
933//
934// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
935#[cfg(feature = "test_build")]
936fn limbs_rem_naive(ns: &[Limb], d: Limb) -> Limb {
937    let d = DoubleLimb::from(d);
938    let mut r = 0;
939    for &n in ns.iter().rev() {
940        r = (DoubleLimb::join_halves(r, n) % d).lower_half();
941    }
942    r
943}
944
945// The high bit of `d` must be set.
946//
947// # Worst-case complexity
948// $T(n) = O(n)$
949//
950// $M(n) = O(1)$
951//
952// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
953//
954// This is equivalent to `mpn_div_qr_1n_pi1` from `mpn/generic/div_qr_1n_pi1.c`, GMP 6.2.1, with
955// `DIV_QR_1N_METHOD == 2`, but not computing the quotient.
956pub fn limbs_mod_limb_normalized<
957    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + SplitInHalf + JoinHalves<Half = T>,
958    T: PrimitiveUnsigned,
959>(
960    ns: &[T],
961    ns_high: T,
962    d: T,
963    d_inv: T,
964) -> T {
965    let len = ns.len();
966    if len == 1 {
967        return mod_by_preinversion::<DT, T>(ns_high, ns[0], d, d_inv);
968    }
969    let power_of_2 = d.wrapping_neg().wrapping_mul(d_inv);
970    let (sum, mut big_carry) = DT::join_halves(ns[len - 1], ns[len - 2])
971        .overflowing_add(DT::from(power_of_2) * DT::from(ns_high));
972    let (mut sum_high, mut sum_low) = sum.split_in_half();
973    for &n in ns[..len - 2].iter().rev() {
974        if big_carry && sum_low.overflowing_add_assign(power_of_2) {
975            sum_low.wrapping_sub_assign(d);
976        }
977        let sum;
978        (sum, big_carry) =
979            DT::join_halves(sum_low, n).overflowing_add(DT::from(sum_high) * DT::from(power_of_2));
980        sum_high = sum.upper_half();
981        sum_low = sum.lower_half();
982    }
983    if big_carry {
984        sum_high.wrapping_sub_assign(d);
985    }
986    if sum_high >= d {
987        sum_high.wrapping_sub_assign(d);
988    }
989    mod_by_preinversion::<DT, T>(sum_high, sum_low, d, d_inv)
990}
991
992// The high bit of `d` must be set.
993//
994// # Worst-case complexity
995// $T(n) = O(n)$
996//
997// $M(n) = O(1)$
998//
999// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1000//
1001// This is equivalent to `mpn_div_qr_1n_pi1` from `mpn/generic/div_qr_1n_pi1.c`, GMP 6.2.1, with
1002// `DIV_QR_1N_METHOD == 2`, but not computing the quotient, and where the input is left-shifted by
1003// `bits`.
1004pub_test! {limbs_mod_limb_normalized_shl<
1005    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + SplitInHalf + JoinHalves<Half = T>,
1006    T: PrimitiveUnsigned,
1007>(
1008    ns: &[T],
1009    ns_high: T,
1010    d: T,
1011    d_inv: T,
1012    bits: u64,
1013) -> T {
1014    let len = ns.len();
1015    if len == 1 {
1016        return mod_by_preinversion::<DT, T>(ns_high, ns[0] << bits, d, d_inv);
1017    }
1018    let power_of_2 = d.wrapping_neg().wrapping_mul(d_inv);
1019    let cobits = T::WIDTH - bits;
1020    let second_highest = ns[len - 2];
1021    let highest_after_shl = (ns[len - 1] << bits) | (second_highest >> cobits);
1022    let mut second_highest_after_shl = second_highest << bits;
1023    if len > 2 {
1024        second_highest_after_shl |= ns[len - 3] >> cobits;
1025    }
1026    let (sum, mut big_carry) = DT::join_halves(highest_after_shl, second_highest_after_shl)
1027        .overflowing_add(DT::from(power_of_2) * DT::from(ns_high));
1028    let (mut sum_high, mut sum_low) = sum.split_in_half();
1029    for j in (0..len - 2).rev() {
1030        if big_carry && sum_low.overflowing_add_assign(power_of_2) {
1031            sum_low.wrapping_sub_assign(d);
1032        }
1033        let mut n = ns[j] << bits;
1034        if j != 0 {
1035            n |= ns[j - 1] >> cobits;
1036        }
1037        let sum;
1038        (sum, big_carry) =
1039            DT::join_halves(sum_low, n).overflowing_add(DT::from(sum_high) * DT::from(power_of_2));
1040        sum_high = sum.upper_half();
1041        sum_low = sum.lower_half();
1042    }
1043    if big_carry {
1044        sum_high.wrapping_sub_assign(d);
1045    }
1046    if sum_high >= d {
1047        sum_high.wrapping_sub_assign(d);
1048    }
1049    mod_by_preinversion::<DT, T>(sum_high, sum_low, d, d_inv)
1050}}
1051
1052// # Worst-case complexity
1053// $T(n) = O(n)$
1054//
1055// $M(n) = O(1)$
1056//
1057// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1058//
1059// This is equivalent to `mpn_div_qr_1` from `mpn/generic/div_qr_1.c`, GMP 6.2.1, where the quotient
1060// is not computed and the remainder is returned. Experiments show that this is always slower than
1061// `limbs_mod_limb`.
1062pub_test! {limbs_mod_limb_alt_1<
1063    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + SplitInHalf + JoinHalves<Half = T>,
1064    T: PrimitiveUnsigned,
1065>(ns: &[T], d: T) -> T {
1066    assert_ne!(d, T::ZERO);
1067    let len = ns.len();
1068    assert!(len > 1);
1069    let len_minus_1 = len - 1;
1070    let mut ns_high = ns[len_minus_1];
1071    let bits = LeadingZeros::leading_zeros(d);
1072    if bits == 0 {
1073        if ns_high >= d {
1074            ns_high -= d;
1075        }
1076        let d_inv = limbs_invert_limb::<DT, T>(d);
1077        limbs_mod_limb_normalized::<DT, T>(&ns[..len_minus_1], ns_high, d, d_inv)
1078    } else {
1079        let d = d << bits;
1080        let cobits = T::WIDTH - bits;
1081        let d_inv = limbs_invert_limb::<DT, T>(d);
1082        let r = mod_by_preinversion::<DT, T>(
1083            ns_high >> cobits,
1084            (ns_high << bits) | (ns[len - 2] >> cobits),
1085            d,
1086            d_inv,
1087        );
1088        limbs_mod_limb_normalized_shl::<DT, T>(&ns[..len_minus_1], r, d, d_inv, bits) >> bits
1089    }
1090}}
1091
1092// Dividing (`n_high`, `n_low`) by `d`, returning the remainder only. Unlike `mod_by_preinversion`,
1093// works also for the case `n_high` == `d`, where the quotient doesn't quite fit in a single limb.
1094//
1095// # Worst-case complexity
1096// Constant time and additional memory.
1097//
1098// This is equivalent to `udiv_rnnd_preinv` from `gmp-impl.h`, GMP 6.2.1.
1099fn mod_by_preinversion_special<
1100    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves + SplitInHalf,
1101    T: PrimitiveUnsigned,
1102>(
1103    n_high: T,
1104    n_low: T,
1105    d: T,
1106    d_inv: T,
1107) -> T {
1108    let (q_high, q_low) = ((DT::from(n_high) * DT::from(d_inv))
1109        .wrapping_add(DT::join_halves(n_high.wrapping_add(T::ONE), n_low)))
1110    .split_in_half();
1111    let mut r = n_low.wrapping_sub(q_high.wrapping_mul(d));
1112    // both > and >= are OK
1113    if r > q_low {
1114        r.wrapping_add_assign(d);
1115    }
1116    if r >= d {
1117        r.wrapping_sub_assign(d);
1118    }
1119    r
1120}
1121
1122// # Worst-case complexity
1123// $T(n) = O(n)$
1124//
1125// $M(n) = O(1)$
1126//
1127// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1128pub_test! {limbs_mod_limb_small_small<
1129    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves + SplitInHalf,
1130    T: PrimitiveUnsigned,
1131>(ns: &[T], d: T, mut r: T) -> T {
1132    let d = DT::from(d);
1133    for &n in ns.iter().rev() {
1134        r = (DT::join_halves(r, n) % d).lower_half();
1135    }
1136    r
1137}}
1138
1139// # Worst-case complexity
1140// $T(n) = O(n)$
1141//
1142// $M(n) = O(1)$
1143//
1144// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1145pub_test! {limbs_mod_limb_small_normalized_large<
1146    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves<Half = T> + SplitInHalf,
1147    T: PrimitiveUnsigned,
1148>(
1149    ns: &[T],
1150    d: T,
1151    mut r: T,
1152) -> T {
1153    let d_inv = limbs_invert_limb::<DT, T>(d);
1154    for &n in ns.iter().rev() {
1155        r = mod_by_preinversion_special::<DT, T>(r, n, d, d_inv);
1156    }
1157    r
1158}}
1159
1160// # Worst-case complexity
1161// $T(n) = O(n)$
1162//
1163// $M(n) = O(1)$
1164//
1165// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1166//
1167// This is equivalent to `mpn_mod_1_norm` from `mpn/generic/mod_1.c`, GMP 6.2.1.
1168pub_test! {
1169#[allow(clippy::absurd_extreme_comparisons)]
1170limbs_mod_limb_small_normalized<
1171    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves<Half = T> + SplitInHalf,
1172    T: PrimitiveUnsigned,
1173>(
1174    ns: &[T],
1175    d: T,
1176) -> T {
1177    let mut len = ns.len();
1178    assert_ne!(len, 0);
1179    assert!(d.get_highest_bit());
1180    // High limb is initial remainder, possibly with one subtraction of d to get r < d.
1181    let mut r = ns[len - 1];
1182    if r >= d {
1183        r -= d;
1184    }
1185    len -= 1;
1186    if len == 0 {
1187        r
1188    } else {
1189        let ns = &ns[..len];
1190        if len < MOD_1_NORM_THRESHOLD {
1191            limbs_mod_limb_small_small::<DT, T>(ns, d, r)
1192        } else {
1193            limbs_mod_limb_small_normalized_large::<DT, T>(ns, d, r)
1194        }
1195    }
1196}}
1197
1198// # Worst-case complexity
1199// $T(n) = O(n)$
1200//
1201// $M(n) = O(1)$
1202//
1203// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1204pub_test! {limbs_mod_limb_small_unnormalized_large<
1205    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves + SplitInHalf,
1206    T: PrimitiveUnsigned,
1207>(
1208    ns: &[T],
1209    mut d: T,
1210    mut r: T,
1211) -> T {
1212    let shift = LeadingZeros::leading_zeros(d);
1213    d <<= shift;
1214    let (ns_last, ns_init) = ns.split_last().unwrap();
1215    let mut previous_n = *ns_last;
1216    let co_shift = T::WIDTH - shift;
1217    r = (r << shift) | (previous_n >> co_shift);
1218    let d_inv = limbs_invert_limb::<DT, T>(d);
1219    for &n in ns_init.iter().rev() {
1220        let shifted_n = (previous_n << shift) | (n >> co_shift);
1221        r = mod_by_preinversion_special::<DT, T>(r, shifted_n, d, d_inv);
1222        previous_n = n;
1223    }
1224    mod_by_preinversion_special::<DT, T>(r, previous_n << shift, d, d_inv) >> shift
1225}}
1226
1227// # Worst-case complexity
1228// $T(n) = O(n)$
1229//
1230// $M(n) = O(1)$
1231//
1232// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1233//
1234// This is equivalent to `mpn_mod_1_unnorm` from `mpn/generic/mod_1.c`, GMP 6.2.1, where
1235// `UDIV_NEEDS_NORMALIZATION` is `false`.
1236pub_test! {
1237#[allow(clippy::absurd_extreme_comparisons)]
1238limbs_mod_limb_small_unnormalized<
1239DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves + SplitInHalf,
1240T: PrimitiveUnsigned,
1241>(ns: &[T], d: T) -> T {
1242    let mut len = ns.len();
1243    assert_ne!(len, 0);
1244    assert_ne!(d, T::ZERO);
1245    assert!(!d.get_highest_bit());
1246    // Skip a division if high < divisor. Having the test here before normalizing will still skip as
1247    // often as possible.
1248    let mut r = ns[len - 1];
1249    if r < d {
1250        len -= 1;
1251        if len == 0 {
1252            return r;
1253        }
1254    } else {
1255        r = T::ZERO;
1256    }
1257    let ns = &ns[..len];
1258    if len < MOD_1_UNNORM_THRESHOLD {
1259        limbs_mod_limb_small_small::<DT, T>(ns, d, r)
1260    } else {
1261        limbs_mod_limb_small_unnormalized_large::<DT, T>(ns, d, r)
1262    }
1263}}
1264
1265// # Worst-case complexity
1266// $T(n) = O(n)$
1267//
1268// $M(n) = O(1)$
1269//
1270// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1271pub_test! {limbs_mod_limb_any_leading_zeros<
1272    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves + SplitInHalf,
1273    T: PrimitiveUnsigned,
1274>(
1275    ns: &[T],
1276    d: T,
1277) -> T {
1278    if MOD_1_1P_METHOD {
1279        limbs_mod_limb_any_leading_zeros_1::<DT, T>(ns, d)
1280    } else {
1281        limbs_mod_limb_any_leading_zeros_2::<DT, T>(ns, d)
1282    }
1283}}
1284
1285// # Worst-case complexity
1286// $T(n) = O(n)$
1287//
1288// $M(n) = O(1)$
1289//
1290// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1291//
1292// This is equivalent to `mpn_mod_1_1p_cps_1` combined with `mpn_mod_1_1p_1` from
1293// `mpn/generic/mod_1.c`, GMP 6.2.1.
1294pub_test! {limbs_mod_limb_any_leading_zeros_1<
1295    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves + SplitInHalf,
1296    T: PrimitiveUnsigned,
1297>(
1298    ns: &[T],
1299    d: T,
1300) -> T {
1301    let len = ns.len();
1302    assert!(len >= 2);
1303    let shift = d.leading_zeros();
1304    let d = d << shift;
1305    let d_inv = limbs_invert_limb::<DT, T>(d);
1306    let mut base_mod_d = d.wrapping_neg();
1307    if shift != 0 {
1308        base_mod_d.wrapping_mul_assign((d_inv >> (T::WIDTH - shift)) | T::power_of_2(shift));
1309    }
1310    assert!(base_mod_d <= d); // not fully reduced mod divisor
1311    let base_pow_2_mod_d =
1312        DT::from(mod_by_preinversion_special::<DT, T>(base_mod_d, T::ZERO, d, d_inv) >> shift);
1313    let base_mod_d = DT::from(base_mod_d >> shift);
1314    let (mut r_hi, mut r_lo) = (DT::from(ns[len - 1]) * base_mod_d)
1315        .wrapping_add(DT::from(ns[len - 2]))
1316        .split_in_half();
1317    for &n in ns[..len - 2].iter().rev() {
1318        (r_hi, r_lo) = (DT::from(r_hi) * base_pow_2_mod_d)
1319            .wrapping_add(DT::from(r_lo) * base_mod_d)
1320            .wrapping_add(DT::from(n))
1321            .split_in_half();
1322    }
1323    if shift != 0 {
1324        r_hi = (r_hi << shift) | (r_lo >> (T::WIDTH - shift));
1325    }
1326    if r_hi >= d {
1327        r_hi.wrapping_sub_assign(d);
1328    }
1329    mod_by_preinversion_special::<DT, T>(r_hi, r_lo << shift, d, d_inv) >> shift
1330}}
1331
1332// # Worst-case complexity
1333// $T(n) = O(n)$
1334//
1335// $M(n) = O(1)$
1336//
1337// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1338//
1339// This is equivalent to `mpn_mod_1_1p_cps_2` combined with `mpn_mod_1_1p_2` from
1340// `mpn/generic/mod_1.c`, GMP 6.2.1.
1341pub_test! {limbs_mod_limb_any_leading_zeros_2<
1342    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves + SplitInHalf,
1343    T: PrimitiveUnsigned,
1344>(
1345    ns: &[T],
1346    d: T,
1347) -> T {
1348    let len = ns.len();
1349    assert!(len >= 2);
1350    let shift = LeadingZeros::leading_zeros(d);
1351    let d = d << shift;
1352    let d_inv = limbs_invert_limb::<DT, T>(d);
1353    let base_mod_d = if shift == 0 {
1354        DT::ZERO
1355    } else {
1356        let base_mod_d = d
1357            .wrapping_neg()
1358            .wrapping_mul((d_inv >> (T::WIDTH - shift)) | T::power_of_2(shift));
1359        assert!(base_mod_d <= d); // not fully reduced mod divisor
1360        DT::from(base_mod_d >> shift)
1361    };
1362    let small_base_pow_2_mod_d = d.wrapping_neg().wrapping_mul(d_inv);
1363    // equality iff divisor = 2 ^ (Limb::WIDTH - 1)
1364    assert!(small_base_pow_2_mod_d <= d);
1365    let base_pow_2_mod_d = DT::from(small_base_pow_2_mod_d);
1366    let mut r_lo = ns[len - 2];
1367    let mut r_hi = ns[len - 1];
1368    if len > 2 {
1369        let (r, mut carry) =
1370            DT::join_halves(r_lo, ns[len - 3]).overflowing_add(DT::from(r_hi) * base_pow_2_mod_d);
1371        (r_hi, r_lo) = r.split_in_half();
1372        for &n in ns[..len - 3].iter().rev() {
1373            if carry && r_lo.overflowing_add_assign(small_base_pow_2_mod_d) {
1374                r_lo.wrapping_sub_assign(d);
1375            }
1376            let r;
1377            (r, carry) =
1378                DT::join_halves(r_lo, n).overflowing_add(DT::from(r_hi) * base_pow_2_mod_d);
1379            (r_hi, r_lo) = r.split_in_half();
1380        }
1381        if carry {
1382            r_hi.wrapping_sub_assign(d);
1383        }
1384    }
1385    if shift != 0 {
1386        let (new_r_hi, t) = (DT::from(r_hi) * base_mod_d).split_in_half();
1387        (r_hi, r_lo) =
1388            (DT::join_halves(new_r_hi, r_lo).wrapping_add(DT::from(t)) << shift).split_in_half();
1389    } else if r_hi >= d {
1390        // might get r_hi == divisor here, but `mod_by_preinversion_special` allows that.
1391        r_hi.wrapping_sub_assign(d);
1392    }
1393    mod_by_preinversion_special::<DT, T>(r_hi, r_lo, d, d_inv) >> shift
1394}}
1395
1396// # Worst-case complexity
1397// $T(n) = O(n)$
1398//
1399// $M(n) = O(1)$
1400//
1401// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1402//
1403// This is equivalent to `mpn_mod_1s_2p_cps` combined with `mpn_mod_1s_2p` from
1404// `mpn/generic/mod_1_2.c`, GMP 6.2.1.
1405pub_test! {limbs_mod_limb_at_least_1_leading_zero<
1406    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves + SplitInHalf,
1407    T: PrimitiveUnsigned,
1408>(
1409    ns: &[T],
1410    d: T,
1411) -> T {
1412    let mut len = ns.len();
1413    assert_ne!(len, 0);
1414    let shift = LeadingZeros::leading_zeros(d);
1415    assert_ne!(shift, 0);
1416    let co_shift = T::WIDTH - shift;
1417    let d = d << shift;
1418    let d_inv = limbs_invert_limb::<DT, T>(d);
1419    let base_mod_d = d
1420        .wrapping_neg()
1421        .wrapping_mul((d_inv >> co_shift) | T::power_of_2(shift));
1422    assert!(base_mod_d <= d); // not fully reduced mod divisor
1423    let base_pow_2_mod_d = mod_by_preinversion_special::<DT, T>(base_mod_d, T::ZERO, d, d_inv);
1424    let base_mod_d = DT::from(base_mod_d >> shift);
1425    let base_pow_3_mod_d = DT::from(
1426        mod_by_preinversion_special::<DT, T>(base_pow_2_mod_d, T::ZERO, d, d_inv) >> shift,
1427    );
1428    let base_pow_2_mod_d = DT::from(base_pow_2_mod_d >> shift);
1429    let (mut r_hi, mut r_lo) = if len.odd() {
1430        len -= 1;
1431        if len == 0 {
1432            let rl = ns[len];
1433            return mod_by_preinversion_special::<DT, T>(rl >> co_shift, rl << shift, d, d_inv)
1434                >> shift;
1435        }
1436        (DT::from(ns[len]) * base_pow_2_mod_d)
1437            .wrapping_add(DT::from(ns[len - 1]) * base_mod_d)
1438            .wrapping_add(DT::from(ns[len - 2]))
1439            .split_in_half()
1440    } else {
1441        (ns[len - 1], ns[len - 2])
1442    };
1443    for chunk in ns[..len - 2].rchunks_exact(2) {
1444        (r_hi, r_lo) = (DT::from(r_hi) * base_pow_3_mod_d)
1445            .wrapping_add(DT::from(r_lo) * base_pow_2_mod_d)
1446            .wrapping_add(DT::from(chunk[1]) * base_mod_d)
1447            .wrapping_add(DT::from(chunk[0]))
1448            .split_in_half();
1449    }
1450    let (r_hi, r_lo) = (DT::from(r_hi) * base_mod_d)
1451        .wrapping_add(DT::from(r_lo))
1452        .split_in_half();
1453    mod_by_preinversion_special::<DT, T>(
1454        (r_hi << shift) | (r_lo >> co_shift),
1455        r_lo << shift,
1456        d,
1457        d_inv,
1458    ) >> shift
1459}}
1460
1461// # Worst-case complexity
1462// $T(n) = O(n)$
1463//
1464// $M(n) = O(1)$
1465//
1466// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1467//
1468// This is equivalent to `mpn_mod_1s_4p_cps` combined with `mpn_mod_1s_4p` from
1469// `mpn/generic/mod_1_4.c`, GMP 6.2.1.
1470pub_test! {limbs_mod_limb_at_least_2_leading_zeros<
1471    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves + SplitInHalf,
1472    T: PrimitiveUnsigned,
1473>(
1474    ns: &[T],
1475    d: T,
1476) -> T {
1477    let mut len = ns.len();
1478    assert_ne!(len, 0);
1479    let shift = LeadingZeros::leading_zeros(d);
1480    assert!(shift >= 2);
1481    let co_shift = T::WIDTH - shift;
1482    let d = d << shift;
1483    let d_inv = limbs_invert_limb::<DT, T>(d);
1484    let base_mod_d = d
1485        .wrapping_neg()
1486        .wrapping_mul((d_inv >> co_shift) | T::power_of_2(shift));
1487    assert!(base_mod_d <= d); // not fully reduced mod divisor
1488    let base_pow_2_mod_d = mod_by_preinversion_special::<DT, T>(base_mod_d, T::ZERO, d, d_inv);
1489    let base_mod_d = DT::from(base_mod_d >> shift);
1490    let base_pow_3_mod_d =
1491        mod_by_preinversion_special::<DT, T>(base_pow_2_mod_d, T::ZERO, d, d_inv);
1492    let base_pow_2_mod_d = DT::from(base_pow_2_mod_d >> shift);
1493    let base_pow_4_mod_d =
1494        mod_by_preinversion_special::<DT, T>(base_pow_3_mod_d, T::ZERO, d, d_inv);
1495    let base_pow_3_mod_d = DT::from(base_pow_3_mod_d >> shift);
1496    let base_pow_5_mod_d = DT::from(
1497        mod_by_preinversion_special::<DT, T>(base_pow_4_mod_d, T::ZERO, d, d_inv) >> shift,
1498    );
1499    let base_pow_4_mod_d = DT::from(base_pow_4_mod_d >> shift);
1500    let (mut r_hi, mut r_lo) = match len.mod_power_of_2(2) {
1501        0 => {
1502            len -= 4;
1503            (DT::from(ns[len + 3]) * base_pow_3_mod_d)
1504                .wrapping_add(DT::from(ns[len + 2]) * base_pow_2_mod_d)
1505                .wrapping_add(DT::from(ns[len + 1]) * base_mod_d)
1506                .wrapping_add(DT::from(ns[len]))
1507                .split_in_half()
1508        }
1509        1 => {
1510            len -= 1;
1511            (T::ZERO, ns[len])
1512        }
1513        2 => {
1514            len -= 2;
1515            (ns[len + 1], ns[len])
1516        }
1517        3 => {
1518            len -= 3;
1519            (DT::from(ns[len + 2]) * base_pow_2_mod_d)
1520                .wrapping_add(DT::from(ns[len + 1]) * base_mod_d)
1521                .wrapping_add(DT::from(ns[len]))
1522                .split_in_half()
1523        }
1524        _ => unreachable!(),
1525    };
1526    for chunk in ns[..len].rchunks_exact(4) {
1527        (r_hi, r_lo) = (DT::from(r_hi) * base_pow_5_mod_d)
1528            .wrapping_add(DT::from(r_lo) * base_pow_4_mod_d)
1529            .wrapping_add(DT::from(chunk[3]) * base_pow_3_mod_d)
1530            .wrapping_add(DT::from(chunk[2]) * base_pow_2_mod_d)
1531            .wrapping_add(DT::from(chunk[1]) * base_mod_d)
1532            .wrapping_add(DT::from(chunk[0]))
1533            .split_in_half();
1534    }
1535    let (r_hi, r_lo) = (DT::from(r_hi) * base_mod_d)
1536        .wrapping_add(DT::from(r_lo))
1537        .split_in_half();
1538    mod_by_preinversion_special::<DT, T>(
1539        (r_hi << shift) | (r_lo >> co_shift),
1540        r_lo << shift,
1541        d,
1542        d_inv,
1543    ) >> shift
1544}}
1545
1546// # Worst-case complexity
1547// $T(n) = O(n)$
1548//
1549// $M(n) = O(1)$
1550//
1551// where $T$ is time, $M$ is additional memory, and $n$ is `ns.len()`.
1552//
1553// This is equivalent to `mpn_mod_1` from `mpn/generic/mod_1.c`, GMP 6.2.1, where `n > 1`.
1554pub_crate_test! {
1555#[allow(clippy::absurd_extreme_comparisons)]
1556limbs_mod_limb_alt_2<
1557    DT: From<T> + HasHalf<Half = T> + PrimitiveUnsigned + JoinHalves + SplitInHalf,
1558    T: PrimitiveUnsigned,
1559>(
1560    ns: &[T],
1561    d: T,
1562) -> T {
1563    let len = ns.len();
1564    assert!(len > 1);
1565    assert_ne!(d, T::ZERO);
1566    if d.get_highest_bit() {
1567        if len < MOD_1N_TO_MOD_1_1_THRESHOLD {
1568            limbs_mod_limb_small_normalized::<DT, T>(ns, d)
1569        } else {
1570            limbs_mod_limb_any_leading_zeros::<DT, T>(ns, d)
1571        }
1572    } else if len < MOD_1U_TO_MOD_1_1_THRESHOLD {
1573        limbs_mod_limb_small_unnormalized::<DT, T>(ns, d)
1574    } else if len < MOD_1_1_TO_MOD_1_2_THRESHOLD {
1575        limbs_mod_limb_any_leading_zeros::<DT, T>(ns, d)
1576    } else if len < MOD_1_2_TO_MOD_1_4_THRESHOLD || d & !(T::MAX >> 2u32) != T::ZERO {
1577        limbs_mod_limb_at_least_1_leading_zero::<DT, T>(ns, d)
1578    } else {
1579        limbs_mod_limb_at_least_2_leading_zeros::<DT, T>(ns, d)
1580    }
1581}}
1582
1583impl Natural {
1584    #[cfg(feature = "test_build")]
1585    pub fn mod_limb_naive(&self, other: Limb) -> Limb {
1586        match (self, other) {
1587            (_, 0) => panic!("division by zero"),
1588            (Self(Small(small)), other) => small % other,
1589            (Self(Large(limbs)), other) => limbs_rem_naive(limbs, other),
1590        }
1591    }
1592
1593    fn rem_limb_ref(&self, other: Limb) -> Limb {
1594        match (self, other) {
1595            (_, 0) => panic!("division by zero"),
1596            (Self(Small(small)), other) => small % other,
1597            (Self(Large(limbs)), other) => limbs_mod_limb::<DoubleLimb, Limb>(limbs, other),
1598        }
1599    }
1600
1601    fn rem_assign_limb(&mut self, other: Limb) {
1602        match (&mut *self, other) {
1603            (_, 0) => panic!("division by zero"),
1604            (Self(Small(small)), other) => *small %= other,
1605            (Self(Large(limbs)), other) => {
1606                *self = Self(Small(limbs_mod_limb::<DoubleLimb, Limb>(limbs, other)));
1607            }
1608        }
1609    }
1610}
1611
1612impl Mod<Self> for Natural {
1613    type Output = Self;
1614
1615    /// Divides a [`Natural`] by another [`Natural`], taking both by value and returning just the
1616    /// remainder.
1617    ///
1618    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
1619    /// \leq r < y$.
1620    ///
1621    /// $$
1622    /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor.
1623    /// $$
1624    ///
1625    /// This function is called `mod_op` rather than `mod` because `mod` is a Rust keyword.
1626    ///
1627    /// # Worst-case complexity
1628    /// $T(n) = O(n \log n \log\log n)$
1629    ///
1630    /// $M(n) = O(n \log n)$
1631    ///
1632    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1633    ///
1634    /// # Panics
1635    /// Panics if `other` is zero.
1636    ///
1637    /// # Examples
1638    /// ```
1639    /// use core::str::FromStr;
1640    /// use malachite_base::num::arithmetic::traits::Mod;
1641    /// use malachite_nz::natural::Natural;
1642    ///
1643    /// // 2 * 10 + 3 = 23
1644    /// assert_eq!(Natural::from(23u32).mod_op(Natural::from(10u32)), 3);
1645    ///
1646    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
1647    /// assert_eq!(
1648    ///     Natural::from_str("1000000000000000000000000")
1649    ///         .unwrap()
1650    ///         .mod_op(Natural::from_str("1234567890987").unwrap()),
1651    ///     530068894399u64
1652    /// );
1653    /// ```
1654    #[inline]
1655    fn mod_op(self, other: Self) -> Self {
1656        self % other
1657    }
1658}
1659
1660impl<'a> Mod<&'a Self> for Natural {
1661    type Output = Self;
1662
1663    /// Divides a [`Natural`] by another [`Natural`], taking the first by value and the second by
1664    /// reference and returning just the remainder.
1665    ///
1666    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
1667    /// \leq r < y$.
1668    ///
1669    /// $$
1670    /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor.
1671    /// $$
1672    ///
1673    /// # Worst-case complexity
1674    /// $T(n) = O(n \log n \log\log n)$
1675    ///
1676    /// $M(n) = O(n \log n)$
1677    ///
1678    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1679    ///
1680    /// # Panics
1681    /// Panics if `other` is zero.
1682    ///
1683    /// # Examples
1684    /// ```
1685    /// use core::str::FromStr;
1686    /// use malachite_base::num::arithmetic::traits::Mod;
1687    /// use malachite_nz::natural::Natural;
1688    ///
1689    /// // 2 * 10 + 3 = 23
1690    /// assert_eq!(Natural::from(23u32).mod_op(&Natural::from(10u32)), 3);
1691    ///
1692    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
1693    /// assert_eq!(
1694    ///     Natural::from_str("1000000000000000000000000")
1695    ///         .unwrap()
1696    ///         .mod_op(&Natural::from_str("1234567890987").unwrap()),
1697    ///     530068894399u64
1698    /// );
1699    /// ```
1700    #[inline]
1701    fn mod_op(self, other: &'a Self) -> Self {
1702        self % other
1703    }
1704}
1705
1706impl Mod<Natural> for &Natural {
1707    type Output = Natural;
1708
1709    /// Divides a [`Natural`] by another [`Natural`], taking the first by reference and the second
1710    /// by value and returning just the remainder.
1711    ///
1712    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
1713    /// \leq r < y$.
1714    ///
1715    /// $$
1716    /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor.
1717    /// $$
1718    ///
1719    /// # Worst-case complexity
1720    /// $T(n) = O(n \log n \log\log n)$
1721    ///
1722    /// $M(n) = O(n \log n)$
1723    ///
1724    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1725    ///
1726    /// # Panics
1727    /// Panics if `other` is zero.
1728    ///
1729    /// # Examples
1730    /// ```
1731    /// use core::str::FromStr;
1732    /// use malachite_base::num::arithmetic::traits::Mod;
1733    /// use malachite_nz::natural::Natural;
1734    ///
1735    /// // 2 * 10 + 3 = 23
1736    /// assert_eq!((&Natural::from(23u32)).mod_op(Natural::from(10u32)), 3);
1737    ///
1738    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
1739    /// assert_eq!(
1740    ///     (&Natural::from_str("1000000000000000000000000").unwrap())
1741    ///         .mod_op(Natural::from_str("1234567890987").unwrap()),
1742    ///     530068894399u64
1743    /// );
1744    /// ```
1745    #[inline]
1746    fn mod_op(self, other: Natural) -> Natural {
1747        self % other
1748    }
1749}
1750
1751impl Mod<&Natural> for &Natural {
1752    type Output = Natural;
1753
1754    /// Divides a [`Natural`] by another [`Natural`], taking both by reference and returning just
1755    /// the remainder.
1756    ///
1757    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
1758    /// \leq r < y$.
1759    ///
1760    /// $$
1761    /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor.
1762    /// $$
1763    ///
1764    /// # Worst-case complexity
1765    /// $T(n) = O(n \log n \log\log n)$
1766    ///
1767    /// $M(n) = O(n \log n)$
1768    ///
1769    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1770    ///
1771    /// # Panics
1772    /// Panics if `other` is zero.
1773    ///
1774    /// # Examples
1775    /// ```
1776    /// use core::str::FromStr;
1777    /// use malachite_base::num::arithmetic::traits::Mod;
1778    /// use malachite_nz::natural::Natural;
1779    ///
1780    /// // 2 * 10 + 3 = 23
1781    /// assert_eq!((&Natural::from(23u32)).mod_op(&Natural::from(10u32)), 3);
1782    ///
1783    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
1784    /// assert_eq!(
1785    ///     (&Natural::from_str("1000000000000000000000000").unwrap())
1786    ///         .mod_op(&Natural::from_str("1234567890987").unwrap()),
1787    ///     530068894399u64
1788    /// );
1789    /// ```
1790    #[inline]
1791    fn mod_op(self, other: &Natural) -> Natural {
1792        self % other
1793    }
1794}
1795
1796impl ModAssign<Self> for Natural {
1797    /// Divides a [`Natural`] by another [`Natural`], taking the second [`Natural`] by value and
1798    /// replacing the first by the remainder.
1799    ///
1800    /// If the quotient were computed, he quotient and remainder would satisfy $x = qy + r$ and $0
1801    /// \leq r < y$.
1802    ///
1803    /// $$
1804    /// x \gets x - y\left \lfloor \frac{x}{y} \right \rfloor.
1805    /// $$
1806    ///
1807    /// # Worst-case complexity
1808    /// $T(n) = O(n \log n \log\log n)$
1809    ///
1810    /// $M(n) = O(n \log n)$
1811    ///
1812    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1813    ///
1814    /// # Panics
1815    /// Panics if `other` is zero.
1816    ///
1817    /// # Examples
1818    /// ```
1819    /// use core::str::FromStr;
1820    /// use malachite_base::num::arithmetic::traits::ModAssign;
1821    /// use malachite_nz::natural::Natural;
1822    ///
1823    /// // 2 * 10 + 3 = 23
1824    /// let mut x = Natural::from(23u32);
1825    /// x.mod_assign(Natural::from(10u32));
1826    /// assert_eq!(x, 3);
1827    ///
1828    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
1829    /// let mut x = Natural::from_str("1000000000000000000000000").unwrap();
1830    /// x.mod_assign(Natural::from_str("1234567890987").unwrap());
1831    /// assert_eq!(x, 530068894399u64);
1832    /// ```
1833    #[inline]
1834    fn mod_assign(&mut self, other: Self) {
1835        *self %= other;
1836    }
1837}
1838
1839impl<'a> ModAssign<&'a Self> for Natural {
1840    /// Divides a [`Natural`] by another [`Natural`], taking the second [`Natural`] by reference and
1841    /// replacing the first by the remainder.
1842    ///
1843    /// If the quotient were computed, he quotient and remainder would satisfy $x = qy + r$ and $0
1844    /// \leq r < y$.
1845    ///
1846    /// $$
1847    /// x \gets x - y\left \lfloor \frac{x}{y} \right \rfloor.
1848    /// $$
1849    ///
1850    /// # Worst-case complexity
1851    /// $T(n) = O(n \log n \log\log n)$
1852    ///
1853    /// $M(n) = O(n \log n)$
1854    ///
1855    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1856    ///
1857    /// # Panics
1858    /// Panics if `other` is zero.
1859    ///
1860    /// # Examples
1861    /// ```
1862    /// use core::str::FromStr;
1863    /// use malachite_base::num::arithmetic::traits::ModAssign;
1864    /// use malachite_nz::natural::Natural;
1865    ///
1866    /// // 2 * 10 + 3 = 23
1867    /// let mut x = Natural::from(23u32);
1868    /// x.mod_assign(&Natural::from(10u32));
1869    /// assert_eq!(x, 3);
1870    ///
1871    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
1872    /// let mut x = Natural::from_str("1000000000000000000000000").unwrap();
1873    /// x.mod_assign(&Natural::from_str("1234567890987").unwrap());
1874    /// assert_eq!(x, 530068894399u64);
1875    /// ```
1876    fn mod_assign(&mut self, other: &'a Self) {
1877        *self %= other;
1878    }
1879}
1880
1881impl Rem<Self> for Natural {
1882    type Output = Self;
1883
1884    /// Divides a [`Natural`] by another [`Natural`], taking both by value and returning just the
1885    /// remainder.
1886    ///
1887    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
1888    /// \leq r < y$.
1889    ///
1890    /// $$
1891    /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor.
1892    /// $$
1893    ///
1894    /// For [`Natural`]s, `rem` is equivalent to [`mod_op`](Mod::mod_op).
1895    ///
1896    /// # Worst-case complexity
1897    /// $T(n) = O(n \log n \log\log n)$
1898    ///
1899    /// $M(n) = O(n \log n)$
1900    ///
1901    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1902    ///
1903    /// # Panics
1904    /// Panics if `other` is zero.
1905    ///
1906    /// # Examples
1907    /// ```
1908    /// use core::str::FromStr;
1909    /// use malachite_nz::natural::Natural;
1910    ///
1911    /// // 2 * 10 + 3 = 23
1912    /// assert_eq!(Natural::from(23u32) % Natural::from(10u32), 3);
1913    ///
1914    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
1915    /// assert_eq!(
1916    ///     Natural::from_str("1000000000000000000000000").unwrap()
1917    ///         % Natural::from_str("1234567890987").unwrap(),
1918    ///     530068894399u64
1919    /// );
1920    /// ```
1921    #[inline]
1922    fn rem(mut self, other: Self) -> Self {
1923        self %= other;
1924        self
1925    }
1926}
1927
1928impl<'a> Rem<&'a Self> for Natural {
1929    type Output = Self;
1930
1931    /// Divides a [`Natural`] by another [`Natural`], taking the first by value and the second by
1932    /// reference and returning just the remainder.
1933    ///
1934    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
1935    /// \leq r < y$.
1936    ///
1937    /// $$
1938    /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor.
1939    /// $$
1940    ///
1941    /// For [`Natural`]s, `rem` is equivalent to [`mod_op`](Mod::mod_op).
1942    ///
1943    /// # Worst-case complexity
1944    /// $T(n) = O(n \log n \log\log n)$
1945    ///
1946    /// $M(n) = O(n \log n)$
1947    ///
1948    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1949    ///
1950    /// # Panics
1951    /// Panics if `other` is zero.
1952    ///
1953    /// # Examples
1954    /// ```
1955    /// use core::str::FromStr;
1956    /// use malachite_nz::natural::Natural;
1957    ///
1958    /// // 2 * 10 + 3 = 23
1959    /// assert_eq!(Natural::from(23u32) % &Natural::from(10u32), 3);
1960    ///
1961    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
1962    /// assert_eq!(
1963    ///     Natural::from_str("1000000000000000000000000").unwrap()
1964    ///         % &Natural::from_str("1234567890987").unwrap(),
1965    ///     530068894399u64
1966    /// );
1967    /// ```
1968    #[inline]
1969    fn rem(mut self, other: &'a Self) -> Self {
1970        self %= other;
1971        self
1972    }
1973}
1974
1975impl Rem<Natural> for &Natural {
1976    type Output = Natural;
1977
1978    /// Divides a [`Natural`] by another [`Natural`], taking the first by reference and the second
1979    /// by value and returning just the remainder.
1980    ///
1981    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
1982    /// \leq r < y$.
1983    ///
1984    /// $$
1985    /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor.
1986    /// $$
1987    ///
1988    /// For [`Natural`]s, `rem` is equivalent to [`mod_op`](Mod::mod_op).
1989    ///
1990    /// # Worst-case complexity
1991    /// $T(n) = O(n \log n \log\log n)$
1992    ///
1993    /// $M(n) = O(n \log n)$
1994    ///
1995    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1996    ///
1997    /// # Panics
1998    /// Panics if `other` is zero.
1999    ///
2000    /// # Examples
2001    /// ```
2002    /// use core::str::FromStr;
2003    /// use malachite_nz::natural::Natural;
2004    ///
2005    /// // 2 * 10 + 3 = 23
2006    /// assert_eq!(&Natural::from(23u32) % Natural::from(10u32), 3);
2007    ///
2008    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
2009    /// assert_eq!(
2010    ///     &Natural::from_str("1000000000000000000000000").unwrap()
2011    ///         % Natural::from_str("1234567890987").unwrap(),
2012    ///     530068894399u64
2013    /// );
2014    /// ```
2015    fn rem(self, other: Natural) -> Natural {
2016        match (self, other) {
2017            (_, Natural::ZERO) => panic!("division by zero"),
2018            (_, Natural::ONE) => Natural::ZERO,
2019            (n, Natural(Small(d))) => Natural(Small(n.rem_limb_ref(d))),
2020            (Natural(Small(_)), _) => self.clone(),
2021            (Natural(Large(ns)), Natural(Large(ds))) => {
2022                if ns.len() >= ds.len() {
2023                    Natural::from_owned_limbs_asc(limbs_mod(ns, &ds))
2024                } else {
2025                    self.clone()
2026                }
2027            }
2028        }
2029    }
2030}
2031
2032impl Rem<&Natural> for &Natural {
2033    type Output = Natural;
2034
2035    /// Divides a [`Natural`] by another [`Natural`], taking both by reference and returning just
2036    /// the remainder.
2037    ///
2038    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
2039    /// \leq r < y$.
2040    ///
2041    /// $$
2042    /// f(x, y) = x - y\left \lfloor \frac{x}{y} \right \rfloor.
2043    /// $$
2044    ///
2045    /// For [`Natural`]s, `rem` is equivalent to [`mod_op`](Mod::mod_op).
2046    ///
2047    /// # Worst-case complexity
2048    /// $T(n) = O(n \log n \log\log n)$
2049    ///
2050    /// $M(n) = O(n \log n)$
2051    ///
2052    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
2053    ///
2054    /// # Panics
2055    /// Panics if `other` is zero.
2056    ///
2057    /// # Examples
2058    /// ```
2059    /// use core::str::FromStr;
2060    /// use malachite_nz::natural::Natural;
2061    ///
2062    /// // 2 * 10 + 3 = 23
2063    /// assert_eq!(&Natural::from(23u32) % &Natural::from(10u32), 3);
2064    ///
2065    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
2066    /// assert_eq!(
2067    ///     &Natural::from_str("1000000000000000000000000").unwrap()
2068    ///         % &Natural::from_str("1234567890987").unwrap(),
2069    ///     530068894399u64
2070    /// );
2071    /// ```
2072    fn rem(self, other: &Natural) -> Natural {
2073        match (self, other) {
2074            (_, &Natural::ZERO) => panic!("division by zero"),
2075            (_, &Natural::ONE) => Natural::ZERO,
2076            (n, d) if core::ptr::eq(n, d) => Natural::ZERO,
2077            (n, Natural(Small(d))) => Natural(Small(n.rem_limb_ref(*d))),
2078            (Natural(Small(_)), _) => self.clone(),
2079            (Natural(Large(ns)), Natural(Large(ds))) => {
2080                if ns.len() >= ds.len() {
2081                    Natural::from_owned_limbs_asc(limbs_mod(ns, ds))
2082                } else {
2083                    self.clone()
2084                }
2085            }
2086        }
2087    }
2088}
2089
2090impl RemAssign<Self> for Natural {
2091    /// Divides a [`Natural`] by another [`Natural`], taking the second [`Natural`] by value and
2092    /// replacing the first by the remainder.
2093    ///
2094    /// If the quotient were computed, he quotient and remainder would satisfy $x = qy + r$ and $0
2095    /// \leq r < y$.
2096    ///
2097    /// $$
2098    /// x \gets x - y\left \lfloor \frac{x}{y} \right \rfloor.
2099    /// $$
2100    ///
2101    /// For [`Natural`]s, `rem_assign` is equivalent to [`mod_assign`](ModAssign::mod_assign).
2102    ///
2103    /// # Worst-case complexity
2104    /// $T(n) = O(n \log n \log\log n)$
2105    ///
2106    /// $M(n) = O(n \log n)$
2107    ///
2108    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
2109    ///
2110    /// # Panics
2111    /// Panics if `other` is zero.
2112    ///
2113    /// # Examples
2114    /// ```
2115    /// use core::str::FromStr;
2116    /// use malachite_nz::natural::Natural;
2117    ///
2118    /// // 2 * 10 + 3 = 23
2119    /// let mut x = Natural::from(23u32);
2120    /// x %= Natural::from(10u32);
2121    /// assert_eq!(x, 3);
2122    ///
2123    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
2124    /// let mut x = Natural::from_str("1000000000000000000000000").unwrap();
2125    /// x %= Natural::from_str("1234567890987").unwrap();
2126    /// assert_eq!(x, 530068894399u64);
2127    /// ```
2128    #[inline]
2129    fn rem_assign(&mut self, other: Self) {
2130        *self %= &other;
2131    }
2132}
2133
2134impl<'a> RemAssign<&'a Self> for Natural {
2135    /// Divides a [`Natural`] by another [`Natural`], taking the second [`Natural`] by reference and
2136    /// replacing the first by the remainder.
2137    ///
2138    /// If the quotient were computed, he quotient and remainder would satisfy $x = qy + r$ and $0
2139    /// \leq r < y$.
2140    ///
2141    /// $$
2142    /// x \gets x - y\left \lfloor \frac{x}{y} \right \rfloor.
2143    /// $$
2144    ///
2145    /// For [`Natural`]s, `rem_assign` is equivalent to [`mod_assign`](ModAssign::mod_assign).
2146    ///
2147    /// # Worst-case complexity
2148    /// $T(n) = O(n \log n \log\log n)$
2149    ///
2150    /// $M(n) = O(n \log n)$
2151    ///
2152    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
2153    ///
2154    /// # Panics
2155    /// Panics if `other` is zero.
2156    ///
2157    /// # Examples
2158    /// ```
2159    /// use core::str::FromStr;
2160    /// use malachite_nz::natural::Natural;
2161    ///
2162    /// // 2 * 10 + 3 = 23
2163    /// let mut x = Natural::from(23u32);
2164    /// x %= &Natural::from(10u32);
2165    /// assert_eq!(x, 3);
2166    ///
2167    /// // 810000006723 * 1234567890987 + 530068894399 = 1000000000000000000000000
2168    /// let mut x = Natural::from_str("1000000000000000000000000").unwrap();
2169    /// x %= &Natural::from_str("1234567890987").unwrap();
2170    /// assert_eq!(x, 530068894399u64);
2171    /// ```
2172    fn rem_assign(&mut self, other: &'a Self) {
2173        match (&mut *self, other) {
2174            (_, &Self::ZERO) => panic!("division by zero"),
2175            (_, &Self::ONE) => *self = Self::ZERO,
2176            (_, Self(Small(d))) => self.rem_assign_limb(*d),
2177            (Self(Small(_)), _) => {}
2178            (Self(Large(ns)), Self(Large(ds))) => {
2179                if ns.len() >= ds.len() {
2180                    let mut rs = vec![0; ds.len()];
2181                    limbs_mod_to_out(&mut rs, ns, ds);
2182                    swap(&mut rs, ns);
2183                    self.trim();
2184                }
2185            }
2186        }
2187    }
2188}
2189
2190impl NegMod<Self> for Natural {
2191    type Output = Self;
2192
2193    /// Divides the negative of a [`Natural`] by another [`Natural`], taking both by value and
2194    /// returning just the remainder.
2195    ///
2196    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy - r$ and $0
2197    /// \leq r < y$.
2198    ///
2199    /// $$
2200    /// f(x, y) = y\left \lceil \frac{x}{y} \right \rceil - x.
2201    /// $$
2202    ///
2203    /// # Worst-case complexity
2204    /// $T(n) = O(n \log n \log\log n)$
2205    ///
2206    /// $M(n) = O(n \log n)$
2207    ///
2208    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
2209    ///
2210    /// # Panics
2211    /// Panics if `other` is zero.
2212    ///
2213    /// # Examples
2214    /// ```
2215    /// use core::str::FromStr;
2216    /// use malachite_base::num::arithmetic::traits::NegMod;
2217    /// use malachite_nz::natural::Natural;
2218    ///
2219    /// // 3 * 10 - 7 = 23
2220    /// assert_eq!(Natural::from(23u32).neg_mod(Natural::from(10u32)), 7);
2221    ///
2222    /// // 810000006724 * 1234567890987 - 704498996588 = 1000000000000000000000000
2223    /// assert_eq!(
2224    ///     Natural::from_str("1000000000000000000000000")
2225    ///         .unwrap()
2226    ///         .neg_mod(Natural::from_str("1234567890987").unwrap()),
2227    ///     704498996588u64
2228    /// );
2229    /// ```
2230    #[inline]
2231    fn neg_mod(mut self, other: Self) -> Self {
2232        self.neg_mod_assign(other);
2233        self
2234    }
2235}
2236
2237impl<'a> NegMod<&'a Self> for Natural {
2238    type Output = Self;
2239
2240    /// Divides the negative of a [`Natural`] by another [`Natural`], taking the first by value and
2241    /// the second by reference and returning just the remainder.
2242    ///
2243    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy - r$ and $0
2244    /// \leq r < y$.
2245    ///
2246    /// $$
2247    /// f(x, y) = y\left \lceil \frac{x}{y} \right \rceil - x.
2248    /// $$
2249    ///
2250    /// # Worst-case complexity
2251    /// $T(n) = O(n \log n \log\log n)$
2252    ///
2253    /// $M(n) = O(n \log n)$
2254    ///
2255    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
2256    ///
2257    /// # Panics
2258    /// Panics if `other` is zero.
2259    ///
2260    /// # Examples
2261    /// ```
2262    /// use core::str::FromStr;
2263    /// use malachite_base::num::arithmetic::traits::NegMod;
2264    /// use malachite_nz::natural::Natural;
2265    ///
2266    /// // 3 * 10 - 7 = 23
2267    /// assert_eq!(Natural::from(23u32).neg_mod(&Natural::from(10u32)), 7);
2268    ///
2269    /// // 810000006724 * 1234567890987 - 704498996588 = 1000000000000000000000000
2270    /// assert_eq!(
2271    ///     Natural::from_str("1000000000000000000000000")
2272    ///         .unwrap()
2273    ///         .neg_mod(&Natural::from_str("1234567890987").unwrap()),
2274    ///     704498996588u64
2275    /// );
2276    /// ```
2277    #[inline]
2278    fn neg_mod(mut self, other: &'a Self) -> Self {
2279        self.neg_mod_assign(other);
2280        self
2281    }
2282}
2283
2284impl NegMod<Natural> for &Natural {
2285    type Output = Natural;
2286
2287    /// Divides the negative of a [`Natural`] by another [`Natural`], taking the first by reference
2288    /// and the second by value and returning just the remainder.
2289    ///
2290    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy - r$ and $0
2291    /// \leq r < y$.
2292    ///
2293    /// $$
2294    /// f(x, y) = y\left \lceil \frac{x}{y} \right \rceil - x.
2295    /// $$
2296    ///
2297    /// # Worst-case complexity
2298    /// $T(n) = O(n \log n \log\log n)$
2299    ///
2300    /// $M(n) = O(n \log n)$
2301    ///
2302    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
2303    ///
2304    /// # Panics
2305    /// Panics if `other` is zero.
2306    ///
2307    /// # Examples
2308    /// ```
2309    /// use core::str::FromStr;
2310    /// use malachite_base::num::arithmetic::traits::NegMod;
2311    /// use malachite_nz::natural::Natural;
2312    ///
2313    /// // 3 * 10 - 7 = 23
2314    /// assert_eq!((&Natural::from(23u32)).neg_mod(Natural::from(10u32)), 7);
2315    ///
2316    /// // 810000006724 * 1234567890987 - 704498996588 = 1000000000000000000000000
2317    /// assert_eq!(
2318    ///     (&Natural::from_str("1000000000000000000000000").unwrap())
2319    ///         .neg_mod(Natural::from_str("1234567890987").unwrap()),
2320    ///     704498996588u64
2321    /// );
2322    /// ```
2323    fn neg_mod(self, other: Natural) -> Natural {
2324        let r = self % &other;
2325        if r == 0 { r } else { other - r }
2326    }
2327}
2328
2329impl NegMod<&Natural> for &Natural {
2330    type Output = Natural;
2331
2332    /// Divides the negative of a [`Natural`] by another [`Natural`], taking both by reference and
2333    /// returning just the remainder.
2334    ///
2335    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy - r$ and $0
2336    /// \leq r < y$.
2337    ///
2338    /// $$
2339    /// f(x, y) = y\left \lceil \frac{x}{y} \right \rceil - x.
2340    /// $$
2341    ///
2342    /// # Worst-case complexity
2343    /// $T(n) = O(n \log n \log\log n)$
2344    ///
2345    /// $M(n) = O(n \log n)$
2346    ///
2347    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
2348    ///
2349    /// # Panics
2350    /// Panics if `other` is zero.
2351    ///
2352    /// # Examples
2353    /// ```
2354    /// use core::str::FromStr;
2355    /// use malachite_base::num::arithmetic::traits::NegMod;
2356    /// use malachite_nz::natural::Natural;
2357    ///
2358    /// // 3 * 10 - 7 = 23
2359    /// assert_eq!((&Natural::from(23u32)).neg_mod(&Natural::from(10u32)), 7);
2360    ///
2361    /// // 810000006724 * 1234567890987 - 704498996588 = 1000000000000000000000000
2362    /// assert_eq!(
2363    ///     (&Natural::from_str("1000000000000000000000000").unwrap())
2364    ///         .neg_mod(&Natural::from_str("1234567890987").unwrap()),
2365    ///     704498996588u64
2366    /// );
2367    /// ```
2368    fn neg_mod(self, other: &Natural) -> Natural {
2369        let r = self % other;
2370        if r == 0 { r } else { other - r }
2371    }
2372}
2373
2374impl NegModAssign<Self> for Natural {
2375    /// Divides the negative of a [`Natural`] by another [`Natural`], taking the second [`Natural`]s
2376    /// by value and replacing the first by the remainder.
2377    ///
2378    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy - r$ and $0
2379    /// \leq r < y$.
2380    ///
2381    /// $$
2382    /// x \gets y\left \lceil \frac{x}{y} \right \rceil - x.
2383    /// $$
2384    ///
2385    /// # Worst-case complexity
2386    /// $T(n) = O(n \log n \log\log n)$
2387    ///
2388    /// $M(n) = O(n \log n)$
2389    ///
2390    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
2391    ///
2392    /// # Panics
2393    /// Panics if `other` is zero.
2394    ///
2395    /// # Examples
2396    /// ```
2397    /// use core::str::FromStr;
2398    /// use malachite_base::num::arithmetic::traits::NegModAssign;
2399    /// use malachite_nz::natural::Natural;
2400    ///
2401    /// // 3 * 10 - 7 = 23
2402    /// let mut x = Natural::from(23u32);
2403    /// x.neg_mod_assign(Natural::from(10u32));
2404    /// assert_eq!(x, 7);
2405    ///
2406    /// // 810000006724 * 1234567890987 - 704498996588 = 1000000000000000000000000
2407    /// let mut x = Natural::from_str("1000000000000000000000000").unwrap();
2408    /// x.neg_mod_assign(Natural::from_str("1234567890987").unwrap());
2409    /// assert_eq!(x, 704498996588u64);
2410    /// ```
2411    fn neg_mod_assign(&mut self, other: Self) {
2412        *self %= &other;
2413        if *self != 0 {
2414            self.sub_right_assign_no_panic(&other);
2415        }
2416    }
2417}
2418
2419impl<'a> NegModAssign<&'a Self> for Natural {
2420    /// Divides the negative of a [`Natural`] by another [`Natural`], taking the second [`Natural`]s
2421    /// by reference and replacing the first by the remainder.
2422    ///
2423    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy - r$ and $0
2424    /// \leq r < y$.
2425    ///
2426    /// $$
2427    /// x \gets y\left \lceil \frac{x}{y} \right \rceil - x.
2428    /// $$
2429    ///
2430    /// # Worst-case complexity
2431    /// $T(n) = O(n \log n \log\log n)$
2432    ///
2433    /// $M(n) = O(n \log n)$
2434    ///
2435    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
2436    ///
2437    /// # Panics
2438    /// Panics if `other` is zero.
2439    ///
2440    /// # Examples
2441    /// ```
2442    /// use core::str::FromStr;
2443    /// use malachite_base::num::arithmetic::traits::NegModAssign;
2444    /// use malachite_nz::natural::Natural;
2445    ///
2446    /// // 3 * 10 - 7 = 23
2447    /// let mut x = Natural::from(23u32);
2448    /// x.neg_mod_assign(&Natural::from(10u32));
2449    /// assert_eq!(x, 7);
2450    ///
2451    /// // 810000006724 * 1234567890987 - 704498996588 = 1000000000000000000000000
2452    /// let mut x = Natural::from_str("1000000000000000000000000").unwrap();
2453    /// x.neg_mod_assign(&Natural::from_str("1234567890987").unwrap());
2454    /// assert_eq!(x, 704498996588u64);
2455    /// ```
2456    fn neg_mod_assign(&mut self, other: &'a Self) {
2457        *self %= other;
2458        if *self != 0 {
2459            self.sub_right_assign_no_panic(other);
2460        }
2461    }
2462}