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}