Skip to main content

malachite_nz/integer/arithmetic/
crt.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the FLINT Library.
4//
5//      Copyright © 2009, 2014 William Hart
6//
7//      Copyright © 2011 Fredrik Johansson
8//
9// This file is part of Malachite.
10//
11// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
12// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
13// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
14
15use crate::integer::Integer;
16use crate::natural::Natural;
17use malachite_base::num::arithmetic::traits::{BalancedCrt, BalancedMod, Crt, UnsignedAbs};
18
19// Computes the balanced Chinese-remainder combination: the unique `x` in `(-m1 * m2 / 2, m1 * m2 /
20// 2]` with `x ≡ r1 mod m1` and `x ≡ r2 mod m2`, or `None` if the moduli are not coprime. `r1`
21// may be any representative in `[-m1, m1)`; `r2` must be reduced mod `m2`.
22//
23// This is fmpz_CRT from fmpz/CRT.c, FLINT 3.6.0, with sign = 1. FLINT compares the canonical
24// solution against itself minus the product directly; reducing with `balanced_mod` is equivalent,
25// since the canonical solution is already in `[0, m1 * m2)`.
26fn balanced_crt_helper(r1: Integer, m1: Natural, r2: Natural, m2: Natural) -> Option<Integer> {
27    // Lift r1 into [0, m1), as _fmpz_CRT does for negative residues.
28    let r1n = if r1 < 0u32 {
29        &m1 - r1.unsigned_abs()
30    } else {
31        r1.unsigned_abs()
32    };
33    let m = &m1 * &m2;
34    let x = r1n.crt(m1, r2, m2)?;
35    Some(Integer::from(x).balanced_mod(Integer::from(m)))
36}
37
38impl BalancedCrt<Natural, Natural, Natural> for Integer {
39    type Output = Self;
40
41    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
42    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
43    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. All four arguments are taken by
44    /// value.
45    ///
46    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
47    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
48    /// reduced modulo `m2`.
49    ///
50    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
51    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
52    ///
53    /// # Worst-case complexity
54    /// $T(n) = O(n (\log n)^2 \log\log n)$
55    ///
56    /// $M(n) = O(n \log n)$
57    ///
58    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
59    /// m2.significant_bits())`.
60    ///
61    /// # Panics
62    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
63    /// than or equal to `m2`.
64    ///
65    /// # Examples
66    /// ```
67    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
68    /// use malachite_base::num::basic::traits::{NegativeOne, One};
69    /// use malachite_nz::integer::Integer;
70    /// use malachite_nz::natural::Natural;
71    ///
72    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
73    /// assert_eq!(
74    ///     Integer::NEGATIVE_ONE.balanced_crt(
75    ///         Natural::from(3u32),
76    ///         Natural::from(3u32),
77    ///         Natural::from(5u32),
78    ///     ),
79    ///     Some(Integer::from(-7))
80    /// );
81    /// assert_eq!(
82    ///     Integer::ONE.balanced_crt(
83    ///         Natural::from(4u32),
84    ///         Natural::from(3u32),
85    ///         Natural::from(6u32),
86    ///     ),
87    ///     None
88    /// );
89    /// ```
90    fn balanced_crt(self, m1: Natural, r2: Natural, m2: Natural) -> Option<Self> {
91        assert!(
92            if self < 0u32 {
93                *self.unsigned_abs_ref() <= m1
94            } else {
95                *self.unsigned_abs_ref() < m1
96            },
97            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
98        );
99        assert!(r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
100        balanced_crt_helper(self, m1, r2, m2)
101    }
102}
103
104impl BalancedCrt<Natural, Natural, &Natural> for Integer {
105    type Output = Self;
106
107    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
108    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
109    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The first, second, and third
110    /// arguments are taken by value and the fourth by reference.
111    ///
112    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
113    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
114    /// reduced modulo `m2`.
115    ///
116    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
117    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
118    ///
119    /// # Worst-case complexity
120    /// $T(n) = O(n (\log n)^2 \log\log n)$
121    ///
122    /// $M(n) = O(n \log n)$
123    ///
124    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
125    /// m2.significant_bits())`.
126    ///
127    /// # Panics
128    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
129    /// than or equal to `m2`.
130    ///
131    /// # Examples
132    /// ```
133    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
134    /// use malachite_base::num::basic::traits::{NegativeOne, One};
135    /// use malachite_nz::integer::Integer;
136    /// use malachite_nz::natural::Natural;
137    ///
138    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
139    /// assert_eq!(
140    ///     Integer::NEGATIVE_ONE.balanced_crt(
141    ///         Natural::from(3u32),
142    ///         Natural::from(3u32),
143    ///         &Natural::from(5u32),
144    ///     ),
145    ///     Some(Integer::from(-7))
146    /// );
147    /// assert_eq!(
148    ///     Integer::ONE.balanced_crt(
149    ///         Natural::from(4u32),
150    ///         Natural::from(3u32),
151    ///         &Natural::from(6u32),
152    ///     ),
153    ///     None
154    /// );
155    /// ```
156    fn balanced_crt(self, m1: Natural, r2: Natural, m2: &Natural) -> Option<Self> {
157        assert!(
158            if self < 0u32 {
159                *self.unsigned_abs_ref() <= m1
160            } else {
161                *self.unsigned_abs_ref() < m1
162            },
163            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
164        );
165        assert!(r2 < *m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
166        balanced_crt_helper(self, m1, r2, m2.clone())
167    }
168}
169
170impl BalancedCrt<Natural, &Natural, Natural> for Integer {
171    type Output = Self;
172
173    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
174    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
175    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The first, second, and fourth
176    /// arguments are taken by value and the third by reference.
177    ///
178    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
179    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
180    /// reduced modulo `m2`.
181    ///
182    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
183    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
184    ///
185    /// # Worst-case complexity
186    /// $T(n) = O(n (\log n)^2 \log\log n)$
187    ///
188    /// $M(n) = O(n \log n)$
189    ///
190    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
191    /// m2.significant_bits())`.
192    ///
193    /// # Panics
194    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
195    /// than or equal to `m2`.
196    ///
197    /// # Examples
198    /// ```
199    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
200    /// use malachite_base::num::basic::traits::{NegativeOne, One};
201    /// use malachite_nz::integer::Integer;
202    /// use malachite_nz::natural::Natural;
203    ///
204    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
205    /// assert_eq!(
206    ///     Integer::NEGATIVE_ONE.balanced_crt(
207    ///         Natural::from(3u32),
208    ///         &Natural::from(3u32),
209    ///         Natural::from(5u32),
210    ///     ),
211    ///     Some(Integer::from(-7))
212    /// );
213    /// assert_eq!(
214    ///     Integer::ONE.balanced_crt(
215    ///         Natural::from(4u32),
216    ///         &Natural::from(3u32),
217    ///         Natural::from(6u32),
218    ///     ),
219    ///     None
220    /// );
221    /// ```
222    fn balanced_crt(self, m1: Natural, r2: &Natural, m2: Natural) -> Option<Self> {
223        assert!(
224            if self < 0u32 {
225                *self.unsigned_abs_ref() <= m1
226            } else {
227                *self.unsigned_abs_ref() < m1
228            },
229            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
230        );
231        assert!(*r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
232        balanced_crt_helper(self, m1, r2.clone(), m2)
233    }
234}
235
236impl BalancedCrt<Natural, &Natural, &Natural> for Integer {
237    type Output = Self;
238
239    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
240    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
241    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The first and second arguments are
242    /// taken by value and the third and fourth by reference.
243    ///
244    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
245    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
246    /// reduced modulo `m2`.
247    ///
248    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
249    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
250    ///
251    /// # Worst-case complexity
252    /// $T(n) = O(n (\log n)^2 \log\log n)$
253    ///
254    /// $M(n) = O(n \log n)$
255    ///
256    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
257    /// m2.significant_bits())`.
258    ///
259    /// # Panics
260    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
261    /// than or equal to `m2`.
262    ///
263    /// # Examples
264    /// ```
265    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
266    /// use malachite_base::num::basic::traits::{NegativeOne, One};
267    /// use malachite_nz::integer::Integer;
268    /// use malachite_nz::natural::Natural;
269    ///
270    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
271    /// assert_eq!(
272    ///     Integer::NEGATIVE_ONE.balanced_crt(
273    ///         Natural::from(3u32),
274    ///         &Natural::from(3u32),
275    ///         &Natural::from(5u32),
276    ///     ),
277    ///     Some(Integer::from(-7))
278    /// );
279    /// assert_eq!(
280    ///     Integer::ONE.balanced_crt(
281    ///         Natural::from(4u32),
282    ///         &Natural::from(3u32),
283    ///         &Natural::from(6u32),
284    ///     ),
285    ///     None
286    /// );
287    /// ```
288    fn balanced_crt(self, m1: Natural, r2: &Natural, m2: &Natural) -> Option<Self> {
289        assert!(
290            if self < 0u32 {
291                *self.unsigned_abs_ref() <= m1
292            } else {
293                *self.unsigned_abs_ref() < m1
294            },
295            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
296        );
297        assert!(r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
298        balanced_crt_helper(self, m1, r2.clone(), m2.clone())
299    }
300}
301
302impl BalancedCrt<&Natural, Natural, Natural> for Integer {
303    type Output = Self;
304
305    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
306    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
307    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The first, third, and fourth
308    /// arguments are taken by value and the second by reference.
309    ///
310    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
311    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
312    /// reduced modulo `m2`.
313    ///
314    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
315    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
316    ///
317    /// # Worst-case complexity
318    /// $T(n) = O(n (\log n)^2 \log\log n)$
319    ///
320    /// $M(n) = O(n \log n)$
321    ///
322    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
323    /// m2.significant_bits())`.
324    ///
325    /// # Panics
326    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
327    /// than or equal to `m2`.
328    ///
329    /// # Examples
330    /// ```
331    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
332    /// use malachite_base::num::basic::traits::{NegativeOne, One};
333    /// use malachite_nz::integer::Integer;
334    /// use malachite_nz::natural::Natural;
335    ///
336    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
337    /// assert_eq!(
338    ///     Integer::NEGATIVE_ONE.balanced_crt(
339    ///         &Natural::from(3u32),
340    ///         Natural::from(3u32),
341    ///         Natural::from(5u32),
342    ///     ),
343    ///     Some(Integer::from(-7))
344    /// );
345    /// assert_eq!(
346    ///     Integer::ONE.balanced_crt(
347    ///         &Natural::from(4u32),
348    ///         Natural::from(3u32),
349    ///         Natural::from(6u32),
350    ///     ),
351    ///     None
352    /// );
353    /// ```
354    fn balanced_crt(self, m1: &Natural, r2: Natural, m2: Natural) -> Option<Self> {
355        assert!(
356            if self < 0u32 {
357                *self.unsigned_abs_ref() <= *m1
358            } else {
359                *self.unsigned_abs_ref() < *m1
360            },
361            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
362        );
363        assert!(r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
364        balanced_crt_helper(self, m1.clone(), r2, m2)
365    }
366}
367
368impl BalancedCrt<&Natural, Natural, &Natural> for Integer {
369    type Output = Self;
370
371    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
372    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
373    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The first and third arguments are
374    /// taken by value and the second and fourth by reference.
375    ///
376    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
377    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
378    /// reduced modulo `m2`.
379    ///
380    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
381    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
382    ///
383    /// # Worst-case complexity
384    /// $T(n) = O(n (\log n)^2 \log\log n)$
385    ///
386    /// $M(n) = O(n \log n)$
387    ///
388    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
389    /// m2.significant_bits())`.
390    ///
391    /// # Panics
392    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
393    /// than or equal to `m2`.
394    ///
395    /// # Examples
396    /// ```
397    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
398    /// use malachite_base::num::basic::traits::{NegativeOne, One};
399    /// use malachite_nz::integer::Integer;
400    /// use malachite_nz::natural::Natural;
401    ///
402    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
403    /// assert_eq!(
404    ///     Integer::NEGATIVE_ONE.balanced_crt(
405    ///         &Natural::from(3u32),
406    ///         Natural::from(3u32),
407    ///         &Natural::from(5u32),
408    ///     ),
409    ///     Some(Integer::from(-7))
410    /// );
411    /// assert_eq!(
412    ///     Integer::ONE.balanced_crt(
413    ///         &Natural::from(4u32),
414    ///         Natural::from(3u32),
415    ///         &Natural::from(6u32),
416    ///     ),
417    ///     None
418    /// );
419    /// ```
420    fn balanced_crt(self, m1: &Natural, r2: Natural, m2: &Natural) -> Option<Self> {
421        assert!(
422            if self < 0u32 {
423                *self.unsigned_abs_ref() <= *m1
424            } else {
425                *self.unsigned_abs_ref() < *m1
426            },
427            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
428        );
429        assert!(r2 < *m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
430        balanced_crt_helper(self, m1.clone(), r2, m2.clone())
431    }
432}
433
434impl BalancedCrt<&Natural, &Natural, Natural> for Integer {
435    type Output = Self;
436
437    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
438    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
439    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The first and fourth arguments are
440    /// taken by value and the second and third by reference.
441    ///
442    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
443    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
444    /// reduced modulo `m2`.
445    ///
446    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
447    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
448    ///
449    /// # Worst-case complexity
450    /// $T(n) = O(n (\log n)^2 \log\log n)$
451    ///
452    /// $M(n) = O(n \log n)$
453    ///
454    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
455    /// m2.significant_bits())`.
456    ///
457    /// # Panics
458    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
459    /// than or equal to `m2`.
460    ///
461    /// # Examples
462    /// ```
463    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
464    /// use malachite_base::num::basic::traits::{NegativeOne, One};
465    /// use malachite_nz::integer::Integer;
466    /// use malachite_nz::natural::Natural;
467    ///
468    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
469    /// assert_eq!(
470    ///     Integer::NEGATIVE_ONE.balanced_crt(
471    ///         &Natural::from(3u32),
472    ///         &Natural::from(3u32),
473    ///         Natural::from(5u32),
474    ///     ),
475    ///     Some(Integer::from(-7))
476    /// );
477    /// assert_eq!(
478    ///     Integer::ONE.balanced_crt(
479    ///         &Natural::from(4u32),
480    ///         &Natural::from(3u32),
481    ///         Natural::from(6u32),
482    ///     ),
483    ///     None
484    /// );
485    /// ```
486    fn balanced_crt(self, m1: &Natural, r2: &Natural, m2: Natural) -> Option<Self> {
487        assert!(
488            if self < 0u32 {
489                *self.unsigned_abs_ref() <= *m1
490            } else {
491                *self.unsigned_abs_ref() < *m1
492            },
493            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
494        );
495        assert!(*r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
496        balanced_crt_helper(self, m1.clone(), r2.clone(), m2)
497    }
498}
499
500impl BalancedCrt<&Natural, &Natural, &Natural> for Integer {
501    type Output = Self;
502
503    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
504    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
505    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The first argument is taken by
506    /// value and the second, third, and fourth by reference.
507    ///
508    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
509    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
510    /// reduced modulo `m2`.
511    ///
512    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
513    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
514    ///
515    /// # Worst-case complexity
516    /// $T(n) = O(n (\log n)^2 \log\log n)$
517    ///
518    /// $M(n) = O(n \log n)$
519    ///
520    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
521    /// m2.significant_bits())`.
522    ///
523    /// # Panics
524    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
525    /// than or equal to `m2`.
526    ///
527    /// # Examples
528    /// ```
529    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
530    /// use malachite_base::num::basic::traits::{NegativeOne, One};
531    /// use malachite_nz::integer::Integer;
532    /// use malachite_nz::natural::Natural;
533    ///
534    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
535    /// assert_eq!(
536    ///     Integer::NEGATIVE_ONE.balanced_crt(
537    ///         &Natural::from(3u32),
538    ///         &Natural::from(3u32),
539    ///         &Natural::from(5u32),
540    ///     ),
541    ///     Some(Integer::from(-7))
542    /// );
543    /// assert_eq!(
544    ///     Integer::ONE.balanced_crt(
545    ///         &Natural::from(4u32),
546    ///         &Natural::from(3u32),
547    ///         &Natural::from(6u32),
548    ///     ),
549    ///     None
550    /// );
551    /// ```
552    fn balanced_crt(self, m1: &Natural, r2: &Natural, m2: &Natural) -> Option<Self> {
553        assert!(
554            if self < 0u32 {
555                *self.unsigned_abs_ref() <= *m1
556            } else {
557                *self.unsigned_abs_ref() < *m1
558            },
559            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
560        );
561        assert!(r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
562        balanced_crt_helper(self, m1.clone(), r2.clone(), m2.clone())
563    }
564}
565
566impl BalancedCrt<Natural, Natural, Natural> for &Integer {
567    type Output = Integer;
568
569    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
570    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
571    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The second, third, and fourth
572    /// arguments are taken by value and the first by reference.
573    ///
574    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
575    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
576    /// reduced modulo `m2`.
577    ///
578    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
579    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
580    ///
581    /// # Worst-case complexity
582    /// $T(n) = O(n (\log n)^2 \log\log n)$
583    ///
584    /// $M(n) = O(n \log n)$
585    ///
586    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
587    /// m2.significant_bits())`.
588    ///
589    /// # Panics
590    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
591    /// than or equal to `m2`.
592    ///
593    /// # Examples
594    /// ```
595    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
596    /// use malachite_base::num::basic::traits::{NegativeOne, One};
597    /// use malachite_nz::integer::Integer;
598    /// use malachite_nz::natural::Natural;
599    ///
600    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
601    /// assert_eq!(
602    ///     (&Integer::NEGATIVE_ONE).balanced_crt(
603    ///         Natural::from(3u32),
604    ///         Natural::from(3u32),
605    ///         Natural::from(5u32),
606    ///     ),
607    ///     Some(Integer::from(-7))
608    /// );
609    /// assert_eq!(
610    ///     (&Integer::ONE).balanced_crt(
611    ///         Natural::from(4u32),
612    ///         Natural::from(3u32),
613    ///         Natural::from(6u32),
614    ///     ),
615    ///     None
616    /// );
617    /// ```
618    fn balanced_crt(self, m1: Natural, r2: Natural, m2: Natural) -> Option<Integer> {
619        assert!(
620            if *self < 0u32 {
621                *self.unsigned_abs_ref() <= m1
622            } else {
623                *self.unsigned_abs_ref() < m1
624            },
625            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
626        );
627        assert!(r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
628        balanced_crt_helper(self.clone(), m1, r2, m2)
629    }
630}
631
632impl BalancedCrt<Natural, Natural, &Natural> for &Integer {
633    type Output = Integer;
634
635    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
636    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
637    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The second and third arguments are
638    /// taken by value and the first and fourth by reference.
639    ///
640    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
641    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
642    /// reduced modulo `m2`.
643    ///
644    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
645    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
646    ///
647    /// # Worst-case complexity
648    /// $T(n) = O(n (\log n)^2 \log\log n)$
649    ///
650    /// $M(n) = O(n \log n)$
651    ///
652    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
653    /// m2.significant_bits())`.
654    ///
655    /// # Panics
656    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
657    /// than or equal to `m2`.
658    ///
659    /// # Examples
660    /// ```
661    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
662    /// use malachite_base::num::basic::traits::{NegativeOne, One};
663    /// use malachite_nz::integer::Integer;
664    /// use malachite_nz::natural::Natural;
665    ///
666    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
667    /// assert_eq!(
668    ///     (&Integer::NEGATIVE_ONE).balanced_crt(
669    ///         Natural::from(3u32),
670    ///         Natural::from(3u32),
671    ///         &Natural::from(5u32),
672    ///     ),
673    ///     Some(Integer::from(-7))
674    /// );
675    /// assert_eq!(
676    ///     (&Integer::ONE).balanced_crt(
677    ///         Natural::from(4u32),
678    ///         Natural::from(3u32),
679    ///         &Natural::from(6u32),
680    ///     ),
681    ///     None
682    /// );
683    /// ```
684    fn balanced_crt(self, m1: Natural, r2: Natural, m2: &Natural) -> Option<Integer> {
685        assert!(
686            if *self < 0u32 {
687                *self.unsigned_abs_ref() <= m1
688            } else {
689                *self.unsigned_abs_ref() < m1
690            },
691            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
692        );
693        assert!(r2 < *m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
694        balanced_crt_helper(self.clone(), m1, r2, m2.clone())
695    }
696}
697
698impl BalancedCrt<Natural, &Natural, Natural> for &Integer {
699    type Output = Integer;
700
701    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
702    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
703    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The second and fourth arguments are
704    /// taken by value and the first and third by reference.
705    ///
706    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
707    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
708    /// reduced modulo `m2`.
709    ///
710    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
711    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
712    ///
713    /// # Worst-case complexity
714    /// $T(n) = O(n (\log n)^2 \log\log n)$
715    ///
716    /// $M(n) = O(n \log n)$
717    ///
718    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
719    /// m2.significant_bits())`.
720    ///
721    /// # Panics
722    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
723    /// than or equal to `m2`.
724    ///
725    /// # Examples
726    /// ```
727    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
728    /// use malachite_base::num::basic::traits::{NegativeOne, One};
729    /// use malachite_nz::integer::Integer;
730    /// use malachite_nz::natural::Natural;
731    ///
732    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
733    /// assert_eq!(
734    ///     (&Integer::NEGATIVE_ONE).balanced_crt(
735    ///         Natural::from(3u32),
736    ///         &Natural::from(3u32),
737    ///         Natural::from(5u32),
738    ///     ),
739    ///     Some(Integer::from(-7))
740    /// );
741    /// assert_eq!(
742    ///     (&Integer::ONE).balanced_crt(
743    ///         Natural::from(4u32),
744    ///         &Natural::from(3u32),
745    ///         Natural::from(6u32),
746    ///     ),
747    ///     None
748    /// );
749    /// ```
750    fn balanced_crt(self, m1: Natural, r2: &Natural, m2: Natural) -> Option<Integer> {
751        assert!(
752            if *self < 0u32 {
753                *self.unsigned_abs_ref() <= m1
754            } else {
755                *self.unsigned_abs_ref() < m1
756            },
757            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
758        );
759        assert!(*r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
760        balanced_crt_helper(self.clone(), m1, r2.clone(), m2)
761    }
762}
763
764impl BalancedCrt<Natural, &Natural, &Natural> for &Integer {
765    type Output = Integer;
766
767    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
768    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
769    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The second argument is taken by
770    /// value and the first, third, and fourth by reference.
771    ///
772    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
773    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
774    /// reduced modulo `m2`.
775    ///
776    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
777    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
778    ///
779    /// # Worst-case complexity
780    /// $T(n) = O(n (\log n)^2 \log\log n)$
781    ///
782    /// $M(n) = O(n \log n)$
783    ///
784    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
785    /// m2.significant_bits())`.
786    ///
787    /// # Panics
788    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
789    /// than or equal to `m2`.
790    ///
791    /// # Examples
792    /// ```
793    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
794    /// use malachite_base::num::basic::traits::{NegativeOne, One};
795    /// use malachite_nz::integer::Integer;
796    /// use malachite_nz::natural::Natural;
797    ///
798    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
799    /// assert_eq!(
800    ///     (&Integer::NEGATIVE_ONE).balanced_crt(
801    ///         Natural::from(3u32),
802    ///         &Natural::from(3u32),
803    ///         &Natural::from(5u32),
804    ///     ),
805    ///     Some(Integer::from(-7))
806    /// );
807    /// assert_eq!(
808    ///     (&Integer::ONE).balanced_crt(
809    ///         Natural::from(4u32),
810    ///         &Natural::from(3u32),
811    ///         &Natural::from(6u32),
812    ///     ),
813    ///     None
814    /// );
815    /// ```
816    fn balanced_crt(self, m1: Natural, r2: &Natural, m2: &Natural) -> Option<Integer> {
817        assert!(
818            if *self < 0u32 {
819                *self.unsigned_abs_ref() <= m1
820            } else {
821                *self.unsigned_abs_ref() < m1
822            },
823            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
824        );
825        assert!(r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
826        balanced_crt_helper(self.clone(), m1, r2.clone(), m2.clone())
827    }
828}
829
830impl BalancedCrt<&Natural, Natural, Natural> for &Integer {
831    type Output = Integer;
832
833    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
834    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
835    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The third and fourth arguments are
836    /// taken by value and the first and second by reference.
837    ///
838    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
839    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
840    /// reduced modulo `m2`.
841    ///
842    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
843    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
844    ///
845    /// # Worst-case complexity
846    /// $T(n) = O(n (\log n)^2 \log\log n)$
847    ///
848    /// $M(n) = O(n \log n)$
849    ///
850    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
851    /// m2.significant_bits())`.
852    ///
853    /// # Panics
854    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
855    /// than or equal to `m2`.
856    ///
857    /// # Examples
858    /// ```
859    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
860    /// use malachite_base::num::basic::traits::{NegativeOne, One};
861    /// use malachite_nz::integer::Integer;
862    /// use malachite_nz::natural::Natural;
863    ///
864    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
865    /// assert_eq!(
866    ///     (&Integer::NEGATIVE_ONE).balanced_crt(
867    ///         &Natural::from(3u32),
868    ///         Natural::from(3u32),
869    ///         Natural::from(5u32),
870    ///     ),
871    ///     Some(Integer::from(-7))
872    /// );
873    /// assert_eq!(
874    ///     (&Integer::ONE).balanced_crt(
875    ///         &Natural::from(4u32),
876    ///         Natural::from(3u32),
877    ///         Natural::from(6u32),
878    ///     ),
879    ///     None
880    /// );
881    /// ```
882    fn balanced_crt(self, m1: &Natural, r2: Natural, m2: Natural) -> Option<Integer> {
883        assert!(
884            if *self < 0u32 {
885                *self.unsigned_abs_ref() <= *m1
886            } else {
887                *self.unsigned_abs_ref() < *m1
888            },
889            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
890        );
891        assert!(r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
892        balanced_crt_helper(self.clone(), m1.clone(), r2, m2)
893    }
894}
895
896impl BalancedCrt<&Natural, Natural, &Natural> for &Integer {
897    type Output = Integer;
898
899    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
900    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
901    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The third argument is taken by
902    /// value and the first, second, and fourth by reference.
903    ///
904    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
905    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
906    /// reduced modulo `m2`.
907    ///
908    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
909    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
910    ///
911    /// # Worst-case complexity
912    /// $T(n) = O(n (\log n)^2 \log\log n)$
913    ///
914    /// $M(n) = O(n \log n)$
915    ///
916    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
917    /// m2.significant_bits())`.
918    ///
919    /// # Panics
920    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
921    /// than or equal to `m2`.
922    ///
923    /// # Examples
924    /// ```
925    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
926    /// use malachite_base::num::basic::traits::{NegativeOne, One};
927    /// use malachite_nz::integer::Integer;
928    /// use malachite_nz::natural::Natural;
929    ///
930    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
931    /// assert_eq!(
932    ///     (&Integer::NEGATIVE_ONE).balanced_crt(
933    ///         &Natural::from(3u32),
934    ///         Natural::from(3u32),
935    ///         &Natural::from(5u32),
936    ///     ),
937    ///     Some(Integer::from(-7))
938    /// );
939    /// assert_eq!(
940    ///     (&Integer::ONE).balanced_crt(
941    ///         &Natural::from(4u32),
942    ///         Natural::from(3u32),
943    ///         &Natural::from(6u32),
944    ///     ),
945    ///     None
946    /// );
947    /// ```
948    fn balanced_crt(self, m1: &Natural, r2: Natural, m2: &Natural) -> Option<Integer> {
949        assert!(
950            if *self < 0u32 {
951                *self.unsigned_abs_ref() <= *m1
952            } else {
953                *self.unsigned_abs_ref() < *m1
954            },
955            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
956        );
957        assert!(r2 < *m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
958        balanced_crt_helper(self.clone(), m1.clone(), r2, m2.clone())
959    }
960}
961
962impl BalancedCrt<&Natural, &Natural, Natural> for &Integer {
963    type Output = Integer;
964
965    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
966    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
967    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. The fourth argument is taken by
968    /// value and the first, second, and third by reference.
969    ///
970    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
971    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
972    /// reduced modulo `m2`.
973    ///
974    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
975    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
976    ///
977    /// # Worst-case complexity
978    /// $T(n) = O(n (\log n)^2 \log\log n)$
979    ///
980    /// $M(n) = O(n \log n)$
981    ///
982    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
983    /// m2.significant_bits())`.
984    ///
985    /// # Panics
986    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
987    /// than or equal to `m2`.
988    ///
989    /// # Examples
990    /// ```
991    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
992    /// use malachite_base::num::basic::traits::{NegativeOne, One};
993    /// use malachite_nz::integer::Integer;
994    /// use malachite_nz::natural::Natural;
995    ///
996    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
997    /// assert_eq!(
998    ///     (&Integer::NEGATIVE_ONE).balanced_crt(
999    ///         &Natural::from(3u32),
1000    ///         &Natural::from(3u32),
1001    ///         Natural::from(5u32),
1002    ///     ),
1003    ///     Some(Integer::from(-7))
1004    /// );
1005    /// assert_eq!(
1006    ///     (&Integer::ONE).balanced_crt(
1007    ///         &Natural::from(4u32),
1008    ///         &Natural::from(3u32),
1009    ///         Natural::from(6u32),
1010    ///     ),
1011    ///     None
1012    /// );
1013    /// ```
1014    fn balanced_crt(self, m1: &Natural, r2: &Natural, m2: Natural) -> Option<Integer> {
1015        assert!(
1016            if *self < 0u32 {
1017                *self.unsigned_abs_ref() <= *m1
1018            } else {
1019                *self.unsigned_abs_ref() < *m1
1020            },
1021            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
1022        );
1023        assert!(*r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
1024        balanced_crt_helper(self.clone(), m1.clone(), r2.clone(), m2)
1025    }
1026}
1027
1028impl BalancedCrt<&Natural, &Natural, &Natural> for &Integer {
1029    type Output = Integer;
1030
1031    /// Combines two congruences by the Chinese remainder theorem, returning the balanced
1032    /// representative: the unique [`Integer`] $x$ with $-m_1m_2/2 < x \leq m_1m_2/2$ that is
1033    /// congruent to `self` modulo `m1` and to `r2` modulo `m2`. All four arguments are taken by
1034    /// reference.
1035    ///
1036    /// Returns `None` if the moduli are not coprime. `self` may be any representative in $[-m_1,
1037    /// m_1)$, negative representatives included, so balanced results may be chained; `r2` must be
1038    /// reduced modulo `m2`.
1039    ///
1040    /// $f(r_1, m_1, r_2, m_2) = \operatorname{Some}(x)$, where $-m_1m_2/2 < x \leq m_1m_2/2$, $x
1041    /// \equiv r_1 \mod m_1$, and $x \equiv r_2 \mod m_2$, if $m_1$ and $m_2$ are coprime.
1042    ///
1043    /// # Worst-case complexity
1044    /// $T(n) = O(n (\log n)^2 \log\log n)$
1045    ///
1046    /// $M(n) = O(n \log n)$
1047    ///
1048    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(m1.significant_bits(),
1049    /// m2.significant_bits())`.
1050    ///
1051    /// # Panics
1052    /// Panics if `self` is less than `-m1` or greater than or equal to `m1`, or if `r2` is greater
1053    /// than or equal to `m2`.
1054    ///
1055    /// # Examples
1056    /// ```
1057    /// use malachite_base::num::arithmetic::traits::BalancedCrt;
1058    /// use malachite_base::num::basic::traits::{NegativeOne, One};
1059    /// use malachite_nz::integer::Integer;
1060    /// use malachite_nz::natural::Natural;
1061    ///
1062    /// // 8 is 2 mod 3 and 3 mod 5, and its balanced representative mod 15 is -7.
1063    /// assert_eq!(
1064    ///     (&Integer::NEGATIVE_ONE).balanced_crt(
1065    ///         &Natural::from(3u32),
1066    ///         &Natural::from(3u32),
1067    ///         &Natural::from(5u32),
1068    ///     ),
1069    ///     Some(Integer::from(-7))
1070    /// );
1071    /// assert_eq!(
1072    ///     (&Integer::ONE).balanced_crt(
1073    ///         &Natural::from(4u32),
1074    ///         &Natural::from(3u32),
1075    ///         &Natural::from(6u32),
1076    ///     ),
1077    ///     None
1078    /// );
1079    /// ```
1080    fn balanced_crt(self, m1: &Natural, r2: &Natural, m2: &Natural) -> Option<Integer> {
1081        assert!(
1082            if *self < 0u32 {
1083                *self.unsigned_abs_ref() <= *m1
1084            } else {
1085                *self.unsigned_abs_ref() < *m1
1086            },
1087            "self must satisfy -m1 <= self < m1, but self = {self} and m1 = {m1}"
1088        );
1089        assert!(r2 < m2, "r2 must be reduced mod m2, but {r2} >= {m2}");
1090        balanced_crt_helper(self.clone(), m1.clone(), r2.clone(), m2.clone())
1091    }
1092}