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}