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}