malachite_nz/integer/arithmetic/eq_mod.rs
1// Copyright © 2025 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5// Copyright © 1991-2018 Free Software Foundation, Inc.
6//
7// This file is part of Malachite.
8//
9// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
10// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
11// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
12
13use crate::integer::Integer;
14use crate::natural::InnerNatural::{Large, Small};
15use crate::natural::Natural;
16use crate::natural::arithmetic::add::{limbs_add, limbs_add_limb};
17use crate::natural::arithmetic::divisible_by::{
18 limbs_divisible_by, limbs_divisible_by_limb, limbs_divisible_by_val_ref,
19};
20use crate::natural::arithmetic::eq_mod::{limbs_eq_limb_mod_limb, limbs_mod_exact_odd_limb};
21use crate::natural::arithmetic::mod_op::limbs_mod_limb;
22use crate::platform::{BMOD_1_TO_MOD_1_THRESHOLD, DoubleLimb, Limb};
23use malachite_base::num::arithmetic::traits::{
24 DivisibleBy, EqMod, EqModPowerOf2, NegMod, PowerOf2,
25};
26use malachite_base::num::basic::integers::PrimitiveInt;
27use malachite_base::num::basic::traits::Zero;
28use malachite_base::num::logic::traits::TrailingZeros;
29
30// Interpreting a slice of `Limb`s as the limbs of a `Natural` in ascending order, determines
31// whether that `Natural` is equal to the negative of a limb mod a given `Limb` m.
32//
33// This function assumes that `m` is nonzero, `limbs` has at least two elements, and the last
34// element of `limbs` is nonzero.
35//
36// # Worst-case complexity
37// $T(n) = O(n)$
38//
39// $M(n) = O(1)$
40//
41// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
42//
43// # Panics
44// Panics if the length of `limbs` is less than 2.
45//
46// This is equivalent to `mpz_congruent_ui_p` from `mpz/cong_ui.c`, GMP 6.2.1, where `a` is
47// negative.
48pub_test! {limbs_eq_neg_limb_mod_limb(xs: &[Limb], y: Limb, m: Limb) -> bool {
49 limbs_eq_limb_mod_limb(xs, y.neg_mod(m), m)
50}}
51
52/// Set r to -n mod d. n >= d is allowed. Can give r > d. d cannot equal 0.
53///
54/// This is equivalent to `NEG_MOD` from `gmp-impl.h`, GMP 6.2.1, where `r` is returned.
55const fn quick_neg_mod(n: Limb, d: Limb) -> Limb {
56 if n <= d {
57 d - n
58 } else {
59 let d = d << d.leading_zeros();
60 (if n <= d { d } else { d << 1 }).wrapping_sub(n)
61 }
62}
63
64// Interpreting two limbs `x` and `y` and slice of `Limb`s `m` as three numbers x, y, and m,
65// determines whether x ≡ -y mod m.
66//
67// This function assumes that the input slice has at least two elements, its last element is
68// nonzero, and `x` and `y` are nonzero.
69//
70// # Worst-case complexity
71// Constant time and additional memory.
72//
73// This is equivalent to `mpz_congruent_p` from `mpz/cong.c`, GMP 6.2.1, where `a` and `d` are
74// positive, `c` is negative, `a` and `d` are one limb long, and `c` is longer than one limb.
75pub_const_test! {limbs_pos_limb_eq_neg_limb_mod(x: Limb, y: Limb, ms: &[Limb]) -> bool {
76 // We are checking whether x ≡ -y mod m; that is, whether x + y = k * m for some k in Z. But
77 // because of the preconditions on m, the lowest possible value of m is `2 ^ Limb::WIDTH`, while
78 // the highest possible value of x + y is `2 ^ (Limb::WIDTH + 1) - 2`, so we have x + y < 2 * m.
79 // This means that k can only be 1, so we're actually checking whether x + y = m.
80 ms.len() == 2 && ms[1] == 1 && {
81 let (sum, overflow) = x.overflowing_add(y);
82 overflow && sum == ms[0]
83 }
84}}
85
86#[allow(clippy::absurd_extreme_comparisons)]
87fn limbs_pos_eq_neg_limb_mod_helper(xs: &[Limb], y: Limb, ms: &[Limb]) -> Option<bool> {
88 let m_len = ms.len();
89 let x_len = xs.len();
90 assert!(m_len > 1);
91 assert!(x_len > 1);
92 assert_ne!(y, 0);
93 assert_ne!(*xs.last().unwrap(), 0);
94 assert_ne!(*ms.last().unwrap(), 0);
95 let m_0 = ms[0];
96 // Check x == y mod low zero bits of m_0. This might catch a few cases of x != y quickly.
97 let twos = TrailingZeros::trailing_zeros(m_0);
98 if !xs[0].wrapping_neg().eq_mod_power_of_2(y, twos) {
99 return Some(false);
100 }
101 // m_0 == 0 is avoided since we don't want to bother handling extra low zero bits if m_1 is even
102 // (would involve borrow if x_0, y_0 != 0).
103 if m_len == 2 && m_0 != 0 {
104 let m_1 = ms[1];
105 if m_1 < Limb::power_of_2(twos) {
106 let m_0 = (m_0 >> twos) | (m_1 << (Limb::WIDTH - twos));
107 let y = quick_neg_mod(y, m_0);
108 return Some(if x_len >= BMOD_1_TO_MOD_1_THRESHOLD {
109 limbs_mod_limb::<DoubleLimb, Limb>(xs, m_0) == if y < m_0 { y } else { y % m_0 }
110 } else {
111 let r = limbs_mod_exact_odd_limb(xs, m_0, y);
112 r == 0 || r == m_0
113 });
114 }
115 }
116 None
117}
118
119// Interpreting a slice of `Limb`s `xs`, a Limb `y`, and another slice of `Limb`s `m` as three
120// numbers x, y, and m, determines whether x ≡ -y mod m. The second input slice is immutable.
121//
122// This function assumes that each of the two input slices have at least two elements, their last
123// elements are nonzero, and `y` is nonzero.
124//
125// # Worst-case complexity
126// $T(n) = O(n \log n \log \log n)$
127//
128// $M(n) = O(n \log n)$
129//
130// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
131//
132// # Panics
133// Panics if the length of `xs` or `ms` is less than 2, if the last element of either of the slices
134// is zero, or if `y` is zero.
135//
136// This is equivalent to `mpz_congruent_p` from `mpz/cong.c`, GMP 6.2.1, where `a` and `d` are
137// positive, `c` is negative, `a` and `d` are longer than one limb, and `c` is one limb long.
138pub_test! {limbs_pos_eq_neg_limb_mod_ref(xs: &[Limb], y: Limb, ms: &[Limb]) -> bool {
139 if let Some(equal) = limbs_pos_eq_neg_limb_mod_helper(xs, y, ms) {
140 return equal;
141 }
142 // calculate |x - y|. Different signs, add
143 let mut scratch = limbs_add_limb(xs, y);
144 scratch.len() >= ms.len() && limbs_divisible_by_val_ref(&mut scratch, ms)
145}}
146
147// Interpreting a slice of `Limb`s `xs`, a Limb `y`, and another slice of `Limb`s `ms` as three
148// numbers x, y, and m, determines whether x ≡ -y mod m. The second input slice is mutable.
149//
150// This function assumes that each of the two input slices have at least two elements, their last
151// elements are nonzero, and `y` is nonzero.
152//
153// # Worst-case complexity
154// $T(n) = O(n \log n \log \log n)$
155//
156// $M(n) = O(n \log n)$
157//
158// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
159//
160// # Panics
161// Panics if the length of `xs` or `ms` is less than 2, if the last element of either of the slices
162// is zero, or if `y` is zero.
163//
164// This is equivalent to `mpz_congruent_p` from `mpz/cong.c`, GMP 6.2.1, where `a` and `d` are
165// positive, `c` is negative, `a` and `d` are longer than one limb, and `c` is one limb long.
166pub_test! {limbs_pos_eq_neg_limb_mod(xs: &[Limb], y: Limb, ms: &mut [Limb]) -> bool {
167 if let Some(equal) = limbs_pos_eq_neg_limb_mod_helper(xs, y, ms) {
168 return equal;
169 }
170 // calculate |x - y|. Different signs, add
171 let mut scratch = limbs_add_limb(xs, y);
172 scratch.len() >= ms.len() && limbs_divisible_by(&mut scratch, ms)
173}}
174
175// Interpreting two slices of `Limb`s `xs` and `ys` and a Limb `m` as three numbers x, y, and m,
176// determines whether x ≡ -y mod m.
177//
178// This function assumes that each of the two input slices have at least two elements, their last
179// elements are nonzero, and `m` is nonzero.
180//
181// # Worst-case complexity
182// $T(n) = O(n)$
183//
184// $M(n) = O(n)$
185//
186// where $T$ is time, $M$ is additional memory, and $n$ is `max(xs.len(), ys.len())`.
187//
188// # Panics
189// Panics if the length of `xs` or `ys` is less than 2, if the last element of either of the slices
190// is zero, or if `m` is zero.
191//
192// This is equivalent to `mpz_congruent_p` from `mpz/cong.c`, GMP 6.2.1, where `a` and `d` are
193// positive, `c` is negative, `a` and `c` are longer than one limb, and `m` is one limb long.
194pub_test! {limbs_pos_eq_neg_mod_limb(xs: &[Limb], ys: &[Limb], m: Limb) -> bool {
195 if xs.len() >= ys.len() {
196 limbs_pos_eq_mod_neg_limb_greater(xs, ys, m)
197 } else {
198 limbs_pos_eq_mod_neg_limb_greater(ys, xs, m)
199 }
200}}
201
202// xs.len() >= ys.len()
203fn limbs_pos_eq_mod_neg_limb_greater(xs: &[Limb], ys: &[Limb], m: Limb) -> bool {
204 assert!(xs.len() > 1);
205 assert!(ys.len() > 1);
206 assert_ne!(*xs.last().unwrap(), 0);
207 assert_ne!(*ys.last().unwrap(), 0);
208 assert_ne!(m, 0);
209 // Check x == y mod low zero bits of m_0. This might catch a few cases of x != y quickly.
210 if !xs[0]
211 .wrapping_neg()
212 .eq_mod_power_of_2(ys[0], TrailingZeros::trailing_zeros(m))
213 {
214 return false;
215 }
216 // calculate |x - y|. Different signs, add
217 limbs_divisible_by_limb(&limbs_add(xs, ys), m)
218}
219
220fn limbs_pos_eq_neg_mod_greater_helper(xs: &[Limb], ys: &[Limb], ms: &[Limb]) -> Option<bool> {
221 assert!(ms.len() > 1);
222 assert!(xs.len() > 1);
223 assert!(ys.len() > 1);
224 assert_ne!(*xs.last().unwrap(), 0);
225 assert_ne!(*ys.last().unwrap(), 0);
226 assert_ne!(*ms.last().unwrap(), 0);
227 // Check x == y mod low zero bits of m_0. This might catch a few cases of x != y quickly.
228 if xs[0]
229 .wrapping_neg()
230 .eq_mod_power_of_2(ys[0], TrailingZeros::trailing_zeros(ms[0]))
231 {
232 None
233 } else {
234 Some(false)
235 }
236}
237
238// Interpreting three slice of `Limb`s as the limbs of three `Natural`s, determines whether the
239// first `Natural` is equal to the negative of the second `Natural` mod the third `Natural`. The
240// second input slice is immutable.
241//
242// This function assumes that each of the three input slices have at least two elements, and their
243// last elements are nonzero.
244//
245// # Worst-case complexity
246// $T(n) = O(n \log n \log \log n)$
247//
248// $M(n) = O(n \log n)$
249//
250// where $T$ is time, $M$ is additional memory, and $n$ is `max(xs.len(), ys.len())`.
251//
252// # Panics
253// Panics if the length of `xs`, `ys`, or `ms` is less than 2, or if the last element of any of the
254// slices is zero.
255//
256// This is equivalent to `mpz_congruent_p` from `mpz/cong.c`, GMP 6.2.1, where `a` and `d` are
257// positive, `c` is negative, and each is longer than one limb.
258pub_test! {limbs_pos_eq_neg_mod_ref(xs: &[Limb], ys: &[Limb], ms: &[Limb]) -> bool {
259 if xs.len() >= ys.len() {
260 limbs_pos_eq_neg_mod_greater_ref(xs, ys, ms)
261 } else {
262 limbs_pos_eq_neg_mod_greater_ref(ys, xs, ms)
263 }
264}}
265
266// xs.len() >= ys.len()
267fn limbs_pos_eq_neg_mod_greater_ref(xs: &[Limb], ys: &[Limb], ms: &[Limb]) -> bool {
268 if let Some(equal) = limbs_pos_eq_neg_mod_greater_helper(xs, ys, ms) {
269 return equal;
270 }
271 // calculate |x - y|. Different signs, add
272 let mut scratch = limbs_add(xs, ys);
273 scratch.len() >= ms.len() && limbs_divisible_by_val_ref(&mut scratch, ms)
274}
275
276// Interpreting three slice of `Limb`s as the limbs of three `Natural`s, determines whether the
277// first `Natural` is equal to the negative of the second `Natural` mod the third `Natural`. The
278// second input slice is mutable.
279//
280// This function assumes that each of the three input slices have at least two elements, and their
281// last elements are nonzero.
282//
283// # Worst-case complexity
284// $T(n) = O(n \log n \log \log n)$
285//
286// $M(n) = O(n \log n)$
287//
288// where $T$ is time, $M$ is additional memory, and $n$ is `max(xs.len(), ys.len())`.
289//
290// # Panics
291// Panics if the length of `xs`, `ys`, or `ms` is less than 2, or if the last element of any of the
292// slices is zero.
293//
294// This is equivalent to `mpz_congruent_p` from `mpz/cong.c`, GMP 6.2.1, where `a` and `d` are
295// positive, `c` is negative, and each is longer than one limb.
296pub_test! {limbs_pos_eq_neg_mod(xs: &[Limb], ys: &[Limb], ms: &mut [Limb]) -> bool {
297 if xs.len() >= ys.len() {
298 limbs_pos_eq_neg_mod_greater(xs, ys, ms)
299 } else {
300 limbs_pos_eq_neg_mod_greater(ys, xs, ms)
301 }
302}}
303
304// xs.len() >= ys.len()
305fn limbs_pos_eq_neg_mod_greater(xs: &[Limb], ys: &[Limb], ms: &mut [Limb]) -> bool {
306 if let Some(equal) = limbs_pos_eq_neg_mod_greater_helper(xs, ys, ms) {
307 return equal;
308 }
309 // calculate |x - y|. Different signs, add
310 let mut scratch = limbs_add(xs, ys);
311 scratch.len() >= ms.len() && limbs_divisible_by(&mut scratch, ms)
312}
313
314impl Natural {
315 fn eq_neg_limb_mod_limb(&self, other: Limb, m: Limb) -> bool {
316 m != 0
317 && match self {
318 Natural(Small(small)) => small % m == other.neg_mod(m),
319 Natural(Large(limbs)) => limbs_eq_neg_limb_mod_limb(limbs, other, m),
320 }
321 }
322
323 fn pos_eq_neg_mod(&self, other: &Natural, m: Natural) -> bool {
324 match (self, other, m) {
325 (_, _, Natural::ZERO) => false,
326 (x, &Natural::ZERO, m) => x.divisible_by(m),
327 (&Natural::ZERO, y, m) => y.divisible_by(m),
328 (x, &Natural(Small(y)), Natural(Small(m))) => x.eq_neg_limb_mod_limb(y, m),
329 (&Natural(Small(x)), y, Natural(Small(m))) => y.eq_neg_limb_mod_limb(x, m),
330 (&Natural(Small(x)), &Natural(Small(y)), Natural(Large(ref m))) => {
331 limbs_pos_limb_eq_neg_limb_mod(x, y, m)
332 }
333 (&Natural(Large(ref xs)), &Natural(Large(ref ys)), Natural(Small(m))) => {
334 limbs_pos_eq_neg_mod_limb(xs, ys, m)
335 }
336 (&Natural(Large(ref xs)), &Natural(Small(y)), Natural(Large(ref mut m))) => {
337 limbs_pos_eq_neg_limb_mod(xs, y, m)
338 }
339 (&Natural(Small(x)), &Natural(Large(ref ys)), Natural(Large(ref mut m))) => {
340 limbs_pos_eq_neg_limb_mod(ys, x, m)
341 }
342 (&Natural(Large(ref xs)), &Natural(Large(ref ys)), Natural(Large(ref mut m))) => {
343 limbs_pos_eq_neg_mod(xs, ys, m)
344 }
345 }
346 }
347
348 fn pos_eq_neg_mod_ref(&self, other: &Natural, m: &Natural) -> bool {
349 match (self, other, m) {
350 (_, _, &Natural::ZERO) => false,
351 (x, &Natural::ZERO, m) => x.divisible_by(m),
352 (&Natural::ZERO, y, m) => y.divisible_by(m),
353 (x, &Natural(Small(y)), &Natural(Small(m))) => x.eq_neg_limb_mod_limb(y, m),
354 (&Natural(Small(x)), y, &Natural(Small(m))) => y.eq_neg_limb_mod_limb(x, m),
355 (&Natural(Small(x)), &Natural(Small(y)), &Natural(Large(ref m))) => {
356 limbs_pos_limb_eq_neg_limb_mod(x, y, m)
357 }
358 (&Natural(Large(ref xs)), &Natural(Large(ref ys)), &Natural(Small(m))) => {
359 limbs_pos_eq_neg_mod_limb(xs, ys, m)
360 }
361 (&Natural(Large(ref xs)), &Natural(Small(y)), &Natural(Large(ref m))) => {
362 limbs_pos_eq_neg_limb_mod_ref(xs, y, m)
363 }
364 (&Natural(Small(x)), &Natural(Large(ref ys)), &Natural(Large(ref m))) => {
365 limbs_pos_eq_neg_limb_mod_ref(ys, x, m)
366 }
367 (&Natural(Large(ref xs)), &Natural(Large(ref ys)), &Natural(Large(ref m))) => {
368 limbs_pos_eq_neg_mod_ref(xs, ys, m)
369 }
370 }
371 }
372}
373
374impl EqMod<Integer, Natural> for Integer {
375 /// Returns whether an [`Integer`] is equivalent to another [`Integer`] modulo a [`Natural`];
376 /// that is, whether the difference between the two [`Integer`]s is a multiple of the
377 /// [`Natural`]. All three numbers are taken by value.
378 ///
379 /// Two [`Integer`]s are equal to each other modulo 0 iff they are equal.
380 ///
381 /// $f(x, y, m) = (x \equiv y \mod m)$.
382 ///
383 /// $f(x, y, m) = (\exists k \in \Z : x - y = km)$.
384 ///
385 /// # Worst-case complexity
386 /// $T(n) = O(n \log n \log \log n)$
387 ///
388 /// $M(n) = O(n \log n)$
389 ///
390 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
391 /// other.significant_bits())`.
392 ///
393 /// # Examples
394 /// ```
395 /// use core::str::FromStr;
396 /// use malachite_base::num::arithmetic::traits::EqMod;
397 /// use malachite_nz::integer::Integer;
398 /// use malachite_nz::natural::Natural;
399 ///
400 /// assert_eq!(
401 /// Integer::from(123).eq_mod(Integer::from(223), Natural::from(100u32)),
402 /// true
403 /// );
404 /// assert_eq!(
405 /// Integer::from_str("1000000987654").unwrap().eq_mod(
406 /// Integer::from_str("-999999012346").unwrap(),
407 /// Natural::from_str("1000000000000").unwrap()
408 /// ),
409 /// true
410 /// );
411 /// assert_eq!(
412 /// Integer::from_str("1000000987654").unwrap().eq_mod(
413 /// Integer::from_str("2000000987655").unwrap(),
414 /// Natural::from_str("1000000000000").unwrap()
415 /// ),
416 /// false
417 /// );
418 /// ```
419 fn eq_mod(self, other: Integer, m: Natural) -> bool {
420 if self.sign == other.sign {
421 self.abs.eq_mod(other.abs, m)
422 } else {
423 self.abs.pos_eq_neg_mod(&other.abs, m)
424 }
425 }
426}
427
428impl EqMod<Integer, &Natural> for Integer {
429 /// Returns whether an [`Integer`] is equivalent to another [`Integer`] modulo a [`Natural`];
430 /// that is, whether the difference between the two [`Integer`]s is a multiple of the
431 /// [`Natural`]. The first two numbers are taken by value and the third by reference.
432 ///
433 /// Two [`Integer`]s are equal to each other modulo 0 iff they are equal.
434 ///
435 /// $f(x, y, m) = (x \equiv y \mod m)$.
436 ///
437 /// $f(x, y, m) = (\exists k \in \Z : x - y = km)$.
438 ///
439 /// # Worst-case complexity
440 /// $T(n) = O(n \log n \log \log n)$
441 ///
442 /// $M(n) = O(n \log n)$
443 ///
444 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
445 /// other.significant_bits())`.
446 ///
447 /// # Examples
448 /// ```
449 /// use core::str::FromStr;
450 /// use malachite_base::num::arithmetic::traits::EqMod;
451 /// use malachite_nz::integer::Integer;
452 /// use malachite_nz::natural::Natural;
453 ///
454 /// assert_eq!(
455 /// Integer::from(123).eq_mod(Integer::from(223), &Natural::from(100u32)),
456 /// true
457 /// );
458 /// assert_eq!(
459 /// Integer::from_str("1000000987654").unwrap().eq_mod(
460 /// Integer::from_str("-999999012346").unwrap(),
461 /// &Natural::from_str("1000000000000").unwrap()
462 /// ),
463 /// true
464 /// );
465 /// assert_eq!(
466 /// Integer::from_str("1000000987654").unwrap().eq_mod(
467 /// Integer::from_str("2000000987655").unwrap(),
468 /// &Natural::from_str("1000000000000").unwrap()
469 /// ),
470 /// false
471 /// );
472 /// ```
473 fn eq_mod(self, other: Integer, m: &Natural) -> bool {
474 if self.sign == other.sign {
475 self.abs.eq_mod(other.abs, m)
476 } else {
477 self.abs.pos_eq_neg_mod_ref(&other.abs, m)
478 }
479 }
480}
481
482impl EqMod<&Integer, Natural> for Integer {
483 /// Returns whether an [`Integer`] is equivalent to another [`Integer`] modulo a [`Natural`];
484 /// that is, whether the difference between the two [`Integer`]s is a multiple of the
485 /// [`Natural`]. The first and third numbers are taken by value and the second by reference.
486 ///
487 /// Two [`Integer`]s are equal to each other modulo 0 iff they are equal.
488 ///
489 /// $f(x, y, m) = (x \equiv y \mod m)$.
490 ///
491 /// $f(x, y, m) = (\exists k \in \Z : x - y = km)$.
492 ///
493 /// # Worst-case complexity
494 /// $T(n) = O(n \log n \log \log n)$
495 ///
496 /// $M(n) = O(n \log n)$
497 ///
498 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
499 /// other.significant_bits())`.
500 ///
501 /// # Examples
502 /// ```
503 /// use core::str::FromStr;
504 /// use malachite_base::num::arithmetic::traits::EqMod;
505 /// use malachite_nz::integer::Integer;
506 /// use malachite_nz::natural::Natural;
507 ///
508 /// assert_eq!(
509 /// Integer::from(123).eq_mod(&Integer::from(223), Natural::from(100u32)),
510 /// true
511 /// );
512 /// assert_eq!(
513 /// Integer::from_str("1000000987654").unwrap().eq_mod(
514 /// &Integer::from_str("-999999012346").unwrap(),
515 /// Natural::from_str("1000000000000").unwrap()
516 /// ),
517 /// true
518 /// );
519 /// assert_eq!(
520 /// Integer::from_str("1000000987654").unwrap().eq_mod(
521 /// &Integer::from_str("2000000987655").unwrap(),
522 /// Natural::from_str("1000000000000").unwrap()
523 /// ),
524 /// false
525 /// );
526 /// ```
527 fn eq_mod(self, other: &Integer, m: Natural) -> bool {
528 if self.sign == other.sign {
529 self.abs.eq_mod(&other.abs, m)
530 } else {
531 self.abs.pos_eq_neg_mod(&other.abs, m)
532 }
533 }
534}
535
536impl EqMod<&Integer, &Natural> for Integer {
537 /// Returns whether an [`Integer`] is equivalent to another [`Integer`] modulo a [`Natural`];
538 /// that is, whether the difference between the two [`Integer`]s is a multiple of the
539 /// [`Natural`]. The first number is taken by value and the second and third by reference.
540 ///
541 /// Two [`Integer`]s are equal to each other modulo 0 iff they are equal.
542 ///
543 /// $f(x, y, m) = (x \equiv y \mod m)$.
544 ///
545 /// $f(x, y, m) = (\exists k \in \Z : x - y = km)$.
546 ///
547 /// # Worst-case complexity
548 /// $T(n) = O(n \log n \log \log n)$
549 ///
550 /// $M(n) = O(n \log n)$
551 ///
552 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
553 /// other.significant_bits())`.
554 ///
555 /// # Examples
556 /// ```
557 /// use core::str::FromStr;
558 /// use malachite_base::num::arithmetic::traits::EqMod;
559 /// use malachite_nz::integer::Integer;
560 /// use malachite_nz::natural::Natural;
561 ///
562 /// assert_eq!(
563 /// Integer::from(123).eq_mod(&Integer::from(223), &Natural::from(100u32)),
564 /// true
565 /// );
566 /// assert_eq!(
567 /// Integer::from_str("1000000987654").unwrap().eq_mod(
568 /// &Integer::from_str("-999999012346").unwrap(),
569 /// &Natural::from_str("1000000000000").unwrap()
570 /// ),
571 /// true
572 /// );
573 /// assert_eq!(
574 /// Integer::from_str("1000000987654").unwrap().eq_mod(
575 /// &Integer::from_str("2000000987655").unwrap(),
576 /// &Natural::from_str("1000000000000").unwrap()
577 /// ),
578 /// false
579 /// );
580 /// ```
581 fn eq_mod(self, other: &Integer, m: &Natural) -> bool {
582 if self.sign == other.sign {
583 self.abs.eq_mod(&other.abs, m)
584 } else {
585 self.abs.pos_eq_neg_mod_ref(&other.abs, m)
586 }
587 }
588}
589
590impl EqMod<Integer, Natural> for &Integer {
591 /// Returns whether an [`Integer`] is equivalent to another [`Integer`] modulo a [`Natural`];
592 /// that is, whether the difference between the two [`Integer`]s is a multiple of the
593 /// [`Natural`]. The first number is taken by reference and the second and third by value.
594 ///
595 /// Two [`Integer`]s are equal to each other modulo 0 iff they are equal.
596 ///
597 /// $f(x, y, m) = (x \equiv y \mod m)$.
598 ///
599 /// $f(x, y, m) = (\exists k \in \Z : x - y = km)$.
600 ///
601 /// # Worst-case complexity
602 /// $T(n) = O(n \log n \log \log n)$
603 ///
604 /// $M(n) = O(n \log n)$
605 ///
606 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
607 /// other.significant_bits())`.
608 ///
609 /// # Examples
610 /// ```
611 /// use core::str::FromStr;
612 /// use malachite_base::num::arithmetic::traits::EqMod;
613 /// use malachite_nz::integer::Integer;
614 /// use malachite_nz::natural::Natural;
615 ///
616 /// assert_eq!(
617 /// (&Integer::from(123)).eq_mod(Integer::from(223), Natural::from(100u32)),
618 /// true
619 /// );
620 /// assert_eq!(
621 /// (&Integer::from_str("1000000987654").unwrap()).eq_mod(
622 /// Integer::from_str("-999999012346").unwrap(),
623 /// Natural::from_str("1000000000000").unwrap()
624 /// ),
625 /// true
626 /// );
627 /// assert_eq!(
628 /// (&Integer::from_str("1000000987654").unwrap()).eq_mod(
629 /// Integer::from_str("2000000987655").unwrap(),
630 /// Natural::from_str("1000000000000").unwrap()
631 /// ),
632 /// false
633 /// );
634 /// ```
635 fn eq_mod(self, other: Integer, m: Natural) -> bool {
636 if self.sign == other.sign {
637 (&self.abs).eq_mod(other.abs, m)
638 } else {
639 self.abs.pos_eq_neg_mod(&other.abs, m)
640 }
641 }
642}
643
644impl EqMod<Integer, &Natural> for &Integer {
645 /// Returns whether an [`Integer`] is equivalent to another [`Integer`] modulo a [`Natural`];
646 /// that is, whether the difference between the two [`Integer`]s is a multiple of the
647 /// [`Natural`]. The first and third numbers are taken by reference and the third by value.
648 ///
649 /// Two [`Integer`]s are equal to each other modulo 0 iff they are equal.
650 ///
651 /// $f(x, y, m) = (x \equiv y \mod m)$.
652 ///
653 /// $f(x, y, m) = (\exists k \in \Z : x - y = km)$.
654 ///
655 /// # Worst-case complexity
656 /// $T(n) = O(n \log n \log \log n)$
657 ///
658 /// $M(n) = O(n \log n)$
659 ///
660 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
661 /// other.significant_bits())`.
662 ///
663 /// # Examples
664 /// ```
665 /// use core::str::FromStr;
666 /// use malachite_base::num::arithmetic::traits::EqMod;
667 /// use malachite_nz::integer::Integer;
668 /// use malachite_nz::natural::Natural;
669 ///
670 /// assert_eq!(
671 /// (&Integer::from(123)).eq_mod(Integer::from(223), &Natural::from(100u32)),
672 /// true
673 /// );
674 /// assert_eq!(
675 /// (&Integer::from_str("1000000987654").unwrap()).eq_mod(
676 /// Integer::from_str("-999999012346").unwrap(),
677 /// &Natural::from_str("1000000000000").unwrap()
678 /// ),
679 /// true
680 /// );
681 /// assert_eq!(
682 /// (&Integer::from_str("1000000987654").unwrap()).eq_mod(
683 /// Integer::from_str("2000000987655").unwrap(),
684 /// &Natural::from_str("1000000000000").unwrap()
685 /// ),
686 /// false
687 /// );
688 /// ```
689 fn eq_mod(self, other: Integer, m: &Natural) -> bool {
690 if self.sign == other.sign {
691 (&self.abs).eq_mod(other.abs, m)
692 } else {
693 self.abs.pos_eq_neg_mod_ref(&other.abs, m)
694 }
695 }
696}
697
698impl EqMod<&Integer, Natural> for &Integer {
699 /// Returns whether an [`Integer`] is equivalent to another [`Integer`] modulo a [`Natural`];
700 /// that is, whether the difference between the two [`Integer`]s is a multiple of the
701 /// [`Natural`]. The first two numbers are taken by reference and the third by value.
702 ///
703 /// Two [`Integer`]s are equal to each other modulo 0 iff they are equal.
704 ///
705 /// $f(x, y, m) = (x \equiv y \mod m)$.
706 ///
707 /// $f(x, y, m) = (\exists k \in \Z : x - y = km)$.
708 ///
709 /// # Worst-case complexity
710 /// $T(n) = O(n \log n \log \log n)$
711 ///
712 /// $M(n) = O(n \log n)$
713 ///
714 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
715 /// other.significant_bits())`.
716 ///
717 /// # Examples
718 /// ```
719 /// use core::str::FromStr;
720 /// use malachite_base::num::arithmetic::traits::EqMod;
721 /// use malachite_nz::integer::Integer;
722 /// use malachite_nz::natural::Natural;
723 ///
724 /// assert_eq!(
725 /// (&Integer::from(123)).eq_mod(&Integer::from(223), Natural::from(100u32)),
726 /// true
727 /// );
728 /// assert_eq!(
729 /// (&Integer::from_str("1000000987654").unwrap()).eq_mod(
730 /// &Integer::from_str("-999999012346").unwrap(),
731 /// Natural::from_str("1000000000000").unwrap()
732 /// ),
733 /// true
734 /// );
735 /// assert_eq!(
736 /// (&Integer::from_str("1000000987654").unwrap()).eq_mod(
737 /// &Integer::from_str("2000000987655").unwrap(),
738 /// Natural::from_str("1000000000000").unwrap()
739 /// ),
740 /// false
741 /// );
742 /// ```
743 fn eq_mod(self, other: &Integer, m: Natural) -> bool {
744 if self.sign == other.sign {
745 (&self.abs).eq_mod(&other.abs, m)
746 } else {
747 self.abs.pos_eq_neg_mod(&other.abs, m)
748 }
749 }
750}
751
752impl EqMod<&Integer, &Natural> for &Integer {
753 /// Returns whether an [`Integer`] is equivalent to another [`Integer`] modulo a [`Natural`];
754 /// that is, whether the difference between the two [`Integer`]s is a multiple of the
755 /// [`Natural`]. All three numbers are taken by reference.
756 ///
757 /// Two [`Integer`]s are equal to each other modulo 0 iff they are equal.
758 ///
759 /// $f(x, y, m) = (x \equiv y \mod m)$.
760 ///
761 /// $f(x, y, m) = (\exists k \in \Z : x - y = km)$.
762 ///
763 /// # Worst-case complexity
764 /// $T(n) = O(n \log n \log \log n)$
765 ///
766 /// $M(n) = O(n \log n)$
767 ///
768 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
769 /// other.significant_bits())`.
770 ///
771 /// # Examples
772 /// ```
773 /// use core::str::FromStr;
774 /// use malachite_base::num::arithmetic::traits::EqMod;
775 /// use malachite_nz::integer::Integer;
776 /// use malachite_nz::natural::Natural;
777 ///
778 /// assert_eq!(
779 /// (&Integer::from(123)).eq_mod(&Integer::from(223), &Natural::from(100u32)),
780 /// true
781 /// );
782 /// assert_eq!(
783 /// (&Integer::from_str("1000000987654").unwrap()).eq_mod(
784 /// &Integer::from_str("-999999012346").unwrap(),
785 /// &Natural::from_str("1000000000000").unwrap()
786 /// ),
787 /// true
788 /// );
789 /// assert_eq!(
790 /// (&Integer::from_str("1000000987654").unwrap()).eq_mod(
791 /// &Integer::from_str("2000000987655").unwrap(),
792 /// &Natural::from_str("1000000000000").unwrap()
793 /// ),
794 /// false
795 /// );
796 /// ```
797 fn eq_mod(self, other: &Integer, m: &Natural) -> bool {
798 if self.sign == other.sign {
799 (&self.abs).eq_mod(&other.abs, m)
800 } else {
801 self.abs.pos_eq_neg_mod_ref(&other.abs, m)
802 }
803 }
804}