Skip to main content

malachite_nz/natural/arithmetic/
mod_add.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the FLINT Library.
4//
5//      Copyright © 2019 Daniel Schultz
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::natural::Natural;
14use malachite_base::num::arithmetic::traits::{ModAdd, ModAddAssign};
15
16impl ModAdd<Self, Self> for Natural {
17    type Output = Self;
18
19    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$. The inputs must be already reduced
20    /// modulo $m$. All three [`Natural`]s are taken by value.
21    ///
22    /// $f(x, y, m) = z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
23    ///
24    /// # Worst-case complexity
25    /// $T(n) = O(n)$
26    ///
27    /// $M(n) = O(n)$
28    ///
29    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
30    ///
31    /// # Panics
32    /// Panics if `self` or `other` are greater than or equal to `m`.
33    ///
34    /// # Examples
35    /// ```
36    /// use malachite_base::num::arithmetic::traits::ModAdd;
37    /// use malachite_base::num::basic::traits::Zero;
38    /// use malachite_nz::natural::Natural;
39    ///
40    /// assert_eq!(
41    ///     Natural::ZERO.mod_add(Natural::from(3u32), Natural::from(5u32)),
42    ///     3
43    /// );
44    /// assert_eq!(
45    ///     Natural::from(7u32).mod_add(Natural::from(5u32), Natural::from(10u32)),
46    ///     2
47    /// );
48    /// ```
49    ///
50    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b`, `c`,
51    /// and `m` are taken by value.
52    #[inline]
53    fn mod_add(mut self, other: Self, m: Self) -> Self {
54        self.mod_add_assign(other, m);
55        self
56    }
57}
58
59impl<'a> ModAdd<Self, &'a Self> for Natural {
60    type Output = Self;
61
62    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$. The inputs must be already reduced
63    /// modulo $m$. The first two [`Natural`]s are taken by value and the third by reference.
64    ///
65    /// $f(x, y, m) = z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
66    ///
67    /// # Worst-case complexity
68    /// $T(n) = O(n)$
69    ///
70    /// $M(n) = O(n)$
71    ///
72    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
73    ///
74    /// # Panics
75    /// Panics if `self` or `other` are greater than or equal to `m`.
76    ///
77    /// # Examples
78    /// ```
79    /// use malachite_base::num::arithmetic::traits::ModAdd;
80    /// use malachite_base::num::basic::traits::Zero;
81    /// use malachite_nz::natural::Natural;
82    ///
83    /// assert_eq!(
84    ///     Natural::ZERO.mod_add(Natural::from(3u32), &Natural::from(5u32)),
85    ///     3
86    /// );
87    /// assert_eq!(
88    ///     Natural::from(7u32).mod_add(Natural::from(5u32), &Natural::from(10u32)),
89    ///     2
90    /// );
91    /// ```
92    ///
93    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b` and `c`
94    /// are taken by value and `m` is taken by reference.
95    #[inline]
96    fn mod_add(mut self, other: Self, m: &'a Self) -> Self {
97        self.mod_add_assign(other, m);
98        self
99    }
100}
101
102impl<'a> ModAdd<&'a Self, Self> for Natural {
103    type Output = Self;
104
105    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$. The inputs must be already reduced
106    /// modulo $m$. The first and third [`Natural`]s are taken by value and the second by reference.
107    ///
108    /// $f(x, y, m) = z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
109    ///
110    /// # Worst-case complexity
111    /// $T(n) = O(n)$
112    ///
113    /// $M(n) = O(n)$
114    ///
115    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
116    ///
117    /// # Panics
118    /// Panics if `self` or `other` are greater than or equal to `m`.
119    ///
120    /// # Examples
121    /// ```
122    /// use malachite_base::num::arithmetic::traits::ModAdd;
123    /// use malachite_base::num::basic::traits::Zero;
124    /// use malachite_nz::natural::Natural;
125    ///
126    /// assert_eq!(
127    ///     Natural::ZERO.mod_add(&Natural::from(3u32), Natural::from(5u32)),
128    ///     3
129    /// );
130    /// assert_eq!(
131    ///     Natural::from(7u32).mod_add(&Natural::from(5u32), Natural::from(10u32)),
132    ///     2
133    /// );
134    /// ```
135    ///
136    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b` and `m`
137    /// are taken by value and `c` is taken by reference.
138    #[inline]
139    fn mod_add(mut self, other: &'a Self, m: Self) -> Self {
140        self.mod_add_assign(other, m);
141        self
142    }
143}
144
145impl<'a, 'b> ModAdd<&'a Self, &'b Self> for Natural {
146    type Output = Self;
147
148    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$. The inputs must be already reduced
149    /// modulo $m$. The first [`Natural`] is taken by value and the second and third by reference.
150    ///
151    /// $f(x, y, m) = z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
152    ///
153    /// # Worst-case complexity
154    /// $T(n) = O(n)$
155    ///
156    /// $M(n) = O(n)$
157    ///
158    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
159    ///
160    /// # Panics
161    /// Panics if `self` or `other` are greater than or equal to `m`.
162    ///
163    /// # Examples
164    /// ```
165    /// use malachite_base::num::arithmetic::traits::ModAdd;
166    /// use malachite_base::num::basic::traits::Zero;
167    /// use malachite_nz::natural::Natural;
168    ///
169    /// assert_eq!(
170    ///     Natural::ZERO.mod_add(&Natural::from(3u32), &Natural::from(5u32)),
171    ///     3
172    /// );
173    /// assert_eq!(
174    ///     Natural::from(7u32).mod_add(&Natural::from(5u32), &Natural::from(10u32)),
175    ///     2
176    /// );
177    /// ```
178    ///
179    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b` is
180    /// taken by value and `c` and `m` are taken by reference.
181    #[inline]
182    fn mod_add(mut self, other: &'a Self, m: &'b Self) -> Self {
183        self.mod_add_assign(other, m);
184        self
185    }
186}
187
188impl ModAdd<Natural, Natural> for &Natural {
189    type Output = Natural;
190
191    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$. The inputs must be already reduced
192    /// modulo $m$. The first [`Natural`] is taken by reference and the second and third by value.
193    ///
194    /// $f(x, y, m) = z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
195    ///
196    /// # Worst-case complexity
197    /// $T(n) = O(n)$
198    ///
199    /// $M(n) = O(n)$
200    ///
201    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
202    ///
203    /// # Panics
204    /// Panics if `self` or `other` are greater than or equal to `m`.
205    ///
206    /// # Examples
207    /// ```
208    /// use malachite_base::num::arithmetic::traits::ModAdd;
209    /// use malachite_base::num::basic::traits::Zero;
210    /// use malachite_nz::natural::Natural;
211    ///
212    /// assert_eq!(
213    ///     (&Natural::ZERO)
214    ///         .mod_add(Natural::from(3u32), Natural::from(5u32))
215    ///         .to_string(),
216    ///     "3"
217    /// );
218    /// assert_eq!(
219    ///     (&Natural::from(7u32))
220    ///         .mod_add(Natural::from(5u32), Natural::from(10u32))
221    ///         .to_string(),
222    ///     "2"
223    /// );
224    /// ```
225    ///
226    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b` is
227    /// taken by reference and `c` and `m` are taken by value.
228    #[inline]
229    fn mod_add(self, mut other: Natural, m: Natural) -> Natural {
230        other.mod_add_assign(self, m);
231        other
232    }
233}
234
235impl ModAdd<Natural, &Natural> for &Natural {
236    type Output = Natural;
237
238    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$. The inputs must be already reduced
239    /// modulo $m$. The first and third [`Natural`]s are taken by reference and the second by value.
240    ///
241    /// $f(x, y, m) = z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
242    ///
243    /// # Worst-case complexity
244    /// $T(n) = O(n)$
245    ///
246    /// $M(n) = O(n)$
247    ///
248    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
249    ///
250    /// # Panics
251    /// Panics if `self` or `other` are greater than or equal to `m`.
252    ///
253    /// # Examples
254    /// ```
255    /// use malachite_base::num::arithmetic::traits::ModAdd;
256    /// use malachite_base::num::basic::traits::Zero;
257    /// use malachite_nz::natural::Natural;
258    ///
259    /// assert_eq!(
260    ///     (&Natural::ZERO).mod_add(Natural::from(3u32), &Natural::from(5u32)),
261    ///     3
262    /// );
263    /// assert_eq!(
264    ///     (&Natural::from(7u32)).mod_add(Natural::from(5u32), &Natural::from(10u32)),
265    ///     2
266    /// );
267    /// ```
268    ///
269    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b` and `m`
270    /// are taken by reference and `c` is taken by value.
271    #[inline]
272    fn mod_add(self, mut other: Natural, m: &Natural) -> Natural {
273        other.mod_add_assign(self, m);
274        other
275    }
276}
277
278impl ModAdd<&Natural, Natural> for &Natural {
279    type Output = Natural;
280
281    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$. The inputs must be already reduced
282    /// modulo $m$. The first two [`Natural`]s are taken by reference and the third by value.
283    ///
284    /// $f(x, y, m) = z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
285    ///
286    /// # Worst-case complexity
287    /// $T(n) = O(n)$
288    ///
289    /// $M(n) = O(n)$
290    ///
291    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
292    ///
293    /// # Panics
294    /// Panics if `self` or `other` are greater than or equal to `m`.
295    ///
296    /// # Examples
297    /// ```
298    /// use malachite_base::num::arithmetic::traits::ModAdd;
299    /// use malachite_base::num::basic::traits::Zero;
300    /// use malachite_nz::natural::Natural;
301    ///
302    /// assert_eq!(
303    ///     (&Natural::ZERO).mod_add(&Natural::from(3u32), Natural::from(5u32)),
304    ///     3
305    /// );
306    /// assert_eq!(
307    ///     (&Natural::from(7u32)).mod_add(&Natural::from(5u32), Natural::from(10u32)),
308    ///     2
309    /// );
310    /// ```
311    ///
312    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b` and `c`
313    /// are taken by reference and `m` is taken by value.
314    fn mod_add(self, other: &Natural, m: Natural) -> Natural {
315        assert!(*self < m, "self must be reduced mod m, but {self} >= {m}");
316        assert!(
317            *other < m,
318            "other must be reduced mod m, but {other} >= {m}"
319        );
320        let sum = self + other;
321        if sum < m { sum } else { sum - m }
322    }
323}
324
325impl ModAdd<&Natural, &Natural> for &Natural {
326    type Output = Natural;
327
328    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$. The inputs must be already reduced
329    /// modulo $m$. All three [`Natural`]s are taken by reference.
330    ///
331    /// $f(x, y, m) = z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
332    ///
333    /// # Worst-case complexity
334    /// $T(n) = O(n)$
335    ///
336    /// $M(n) = O(n)$
337    ///
338    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
339    ///
340    /// # Panics
341    /// Panics if `self` or `other` are greater than or equal to `m`.
342    ///
343    /// # Examples
344    /// ```
345    /// use malachite_base::num::arithmetic::traits::ModAdd;
346    /// use malachite_base::num::basic::traits::Zero;
347    /// use malachite_nz::natural::Natural;
348    ///
349    /// assert_eq!(
350    ///     (&Natural::ZERO).mod_add(&Natural::from(3u32), &Natural::from(5u32)),
351    ///     3
352    /// );
353    /// assert_eq!(
354    ///     (&Natural::from(7u32)).mod_add(&Natural::from(5u32), &Natural::from(10u32)),
355    ///     2
356    /// );
357    /// ```
358    ///
359    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b`, `c`,
360    /// and `m` are taken by reference.
361    fn mod_add(self, other: &Natural, m: &Natural) -> Natural {
362        assert!(self < m, "self must be reduced mod m, but {self} >= {m}");
363        assert!(other < m, "other must be reduced mod m, but {other} >= {m}");
364        let sum = self + other;
365        if sum < *m { sum } else { sum - m }
366    }
367}
368
369impl ModAddAssign<Self, Self> for Natural {
370    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$, in place. The inputs must be already
371    /// reduced modulo $m$. Both [`Natural`]s on the right-hand side are taken by value.
372    ///
373    /// $x \gets z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
374    ///
375    /// # Worst-case complexity
376    /// $T(n) = O(n)$
377    ///
378    /// $M(n) = O(n)$
379    ///
380    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
381    ///
382    /// # Panics
383    /// Panics if `self` or `other` are greater than or equal to `m`.
384    ///
385    /// # Examples
386    /// ```
387    /// use malachite_base::num::arithmetic::traits::ModAddAssign;
388    /// use malachite_base::num::basic::traits::Zero;
389    /// use malachite_nz::natural::Natural;
390    ///
391    /// let mut x = Natural::ZERO;
392    /// x.mod_add_assign(Natural::from(3u32), Natural::from(5u32));
393    /// assert_eq!(x, 3);
394    ///
395    /// let mut x = Natural::from(7u32);
396    /// x.mod_add_assign(Natural::from(5u32), Natural::from(10u32));
397    /// assert_eq!(x, 2);
398    /// ```
399    ///
400    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b`, `c`,
401    /// and `m` are taken by value and `a == b`.
402    fn mod_add_assign(&mut self, other: Self, m: Self) {
403        assert!(*self < m, "self must be reduced mod m, but {self} >= {m}");
404        assert!(other < m, "other must be reduced mod m, but {other} >= {m}");
405        *self += other;
406        if *self >= m {
407            *self -= m;
408        }
409    }
410}
411
412impl<'a> ModAddAssign<Self, &'a Self> for Natural {
413    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$, in place. The inputs must be already
414    /// reduced modulo $m$. The first [`Natural`] on the right-hand side is taken by value and the
415    /// second by reference.
416    ///
417    /// $x \gets z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
418    ///
419    /// # Worst-case complexity
420    /// $T(n) = O(n)$
421    ///
422    /// $M(n) = O(n)$
423    ///
424    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
425    ///
426    /// # Panics
427    /// Panics if `self` or `other` are greater than or equal to `m`.
428    ///
429    /// # Examples
430    /// ```
431    /// use malachite_base::num::arithmetic::traits::ModAddAssign;
432    /// use malachite_base::num::basic::traits::Zero;
433    /// use malachite_nz::natural::Natural;
434    ///
435    /// let mut x = Natural::ZERO;
436    /// x.mod_add_assign(Natural::from(3u32), &Natural::from(5u32));
437    /// assert_eq!(x, 3);
438    ///
439    /// let mut x = Natural::from(7u32);
440    /// x.mod_add_assign(Natural::from(5u32), &Natural::from(10u32));
441    /// assert_eq!(x, 2);
442    /// ```
443    ///
444    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b` and `c`
445    /// are taken by value, `m` is taken by reference, and `a == b`.
446    fn mod_add_assign(&mut self, other: Self, m: &'a Self) {
447        assert!(*self < *m, "self must be reduced mod m, but {self} >= {m}");
448        assert!(
449            other < *m,
450            "other must be reduced mod m, but {other} >= {m}"
451        );
452        *self += other;
453        if *self >= *m {
454            *self -= m;
455        }
456    }
457}
458
459impl<'a> ModAddAssign<&'a Self, Self> for Natural {
460    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$, in place. The inputs must be already
461    /// reduced modulo $m$. The first [`Natural`] on the right-hand side is taken by reference and
462    /// the second by value.
463    ///
464    /// $x \gets z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
465    ///
466    /// # Worst-case complexity
467    /// $T(n) = O(n)$
468    ///
469    /// $M(n) = O(n)$
470    ///
471    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
472    ///
473    /// # Panics
474    /// Panics if `self` or `other` are greater than or equal to `m`.
475    ///
476    /// # Examples
477    /// ```
478    /// use malachite_base::num::arithmetic::traits::ModAddAssign;
479    /// use malachite_base::num::basic::traits::Zero;
480    /// use malachite_nz::natural::Natural;
481    ///
482    /// let mut x = Natural::ZERO;
483    /// x.mod_add_assign(&Natural::from(3u32), Natural::from(5u32));
484    /// assert_eq!(x, 3);
485    ///
486    /// let mut x = Natural::from(7u32);
487    /// x.mod_add_assign(&Natural::from(5u32), Natural::from(10u32));
488    /// assert_eq!(x, 2);
489    /// ```
490    ///
491    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b` and `m`
492    /// are taken by value, `c` is taken by reference, and `a == b`.
493    fn mod_add_assign(&mut self, other: &'a Self, m: Self) {
494        assert!(*self < m, "self must be reduced mod m, but {self} >= {m}");
495        assert!(
496            *other < m,
497            "other must be reduced mod m, but {other} >= {m}"
498        );
499        *self += other;
500        if *self >= m {
501            *self -= m;
502        }
503    }
504}
505
506impl<'a, 'b> ModAddAssign<&'a Self, &'b Self> for Natural {
507    /// Adds two [`Natural`]s modulo a third [`Natural`] $m$, in place. The inputs must be already
508    /// reduced modulo $m$. Both [`Natural`]s on the right-hand side are taken by reference.
509    ///
510    /// $x \gets z$, where $x, y, z < m$ and $x + y \equiv z \mod m$.
511    ///
512    /// # Worst-case complexity
513    /// $T(n) = O(n)$
514    ///
515    /// $M(n) = O(n)$
516    ///
517    /// where $T$ is time, $M$ is additional memory, and $n$ is `m.significant_bits()`.
518    ///
519    /// # Panics
520    /// Panics if `self` or `other` are greater than or equal to `m`.
521    ///
522    /// # Examples
523    /// ```
524    /// use malachite_base::num::arithmetic::traits::ModAddAssign;
525    /// use malachite_base::num::basic::traits::Zero;
526    /// use malachite_nz::natural::Natural;
527    ///
528    /// let mut x = Natural::ZERO;
529    /// x.mod_add_assign(&Natural::from(3u32), &Natural::from(5u32));
530    /// assert_eq!(x, 3);
531    ///
532    /// let mut x = Natural::from(7u32);
533    /// x.mod_add_assign(&Natural::from(5u32), &Natural::from(10u32));
534    /// assert_eq!(x, 2);
535    /// ```
536    ///
537    /// This is equivalent to `_fmpz_mod_addN` from `fmpz_mod/add.c`, FLINT 2.7.1, where `b` is
538    /// taken by value, `c` and `m` are taken by reference, and `a == b`.
539    fn mod_add_assign(&mut self, other: &'a Self, m: &'b Self) {
540        assert!(&*self < m, "self must be reduced mod m, but {self} >= {m}");
541        assert!(other < m, "other must be reduced mod m, but {other} >= {m}");
542        *self += other;
543        if *self >= *m {
544            *self -= m;
545        }
546    }
547}