Skip to main content

malachite_nz/integer/arithmetic/
mod_euclidean.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::integer::Integer;
10use crate::natural::Natural;
11use malachite_base::num::arithmetic::traits::{
12    Mod, ModAssign, ModEuclidean, ModEuclideanAssign, UnsignedAbs,
13};
14
15impl ModEuclidean<Self> for Integer {
16    type Output = Natural;
17
18    /// Divides an [`Integer`] by another [`Integer`], taking both by value and returning just the
19    /// remainder. The remainder is nonnegative and is returned as a [`Natural`].
20    ///
21    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
22    /// \leq r < |y|$.
23    ///
24    /// $$
25    /// f(x, y) = x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
26    /// $$
27    ///
28    /// # Worst-case complexity
29    /// $T(n) = O(n \log n \log \log n)$
30    ///
31    /// $M(n) = O(n \log n)$
32    ///
33    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
34    ///
35    /// # Panics
36    /// Panics if `other` is zero.
37    ///
38    /// # Examples
39    /// ```
40    /// use malachite_base::num::arithmetic::traits::ModEuclidean;
41    /// use malachite_nz::integer::Integer;
42    ///
43    /// // 2 * 10 + 3 = 23
44    /// assert_eq!(Integer::from(23).mod_euclidean(Integer::from(10)), 3);
45    ///
46    /// // 3 * -10 + 7 = -23
47    /// assert_eq!(Integer::from(-23).mod_euclidean(Integer::from(-10)), 7);
48    /// ```
49    #[inline]
50    fn mod_euclidean(self, other: Self) -> Natural {
51        let r = self.mod_op(&other);
52        if r < 0u32 {
53            (r - other).unsigned_abs()
54        } else {
55            r.unsigned_abs()
56        }
57    }
58}
59
60impl ModEuclidean<&Self> for Integer {
61    type Output = Natural;
62
63    /// Divides an [`Integer`] by another [`Integer`], taking the first by value and the second by
64    /// reference and returning just the remainder. The remainder is nonnegative and is returned as
65    /// a [`Natural`].
66    ///
67    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
68    /// \leq r < |y|$.
69    ///
70    /// $$
71    /// f(x, y) = x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
72    /// $$
73    ///
74    /// # Worst-case complexity
75    /// $T(n) = O(n \log n \log \log n)$
76    ///
77    /// $M(n) = O(n \log n)$
78    ///
79    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
80    ///
81    /// # Panics
82    /// Panics if `other` is zero.
83    ///
84    /// # Examples
85    /// ```
86    /// use malachite_base::num::arithmetic::traits::ModEuclidean;
87    /// use malachite_nz::integer::Integer;
88    ///
89    /// // -3 * 10 + 7 = -23
90    /// assert_eq!(Integer::from(-23).mod_euclidean(&Integer::from(10)), 7);
91    /// ```
92    #[inline]
93    fn mod_euclidean(self, other: &Self) -> Natural {
94        let r = self.mod_op(other);
95        if r < 0u32 {
96            (r - other).unsigned_abs()
97        } else {
98            r.unsigned_abs()
99        }
100    }
101}
102
103impl ModEuclidean<Integer> for &Integer {
104    type Output = Natural;
105
106    /// Divides an [`Integer`] by another [`Integer`], taking the first by reference and the second
107    /// by value and returning just the remainder. The remainder is nonnegative and is returned as a
108    /// [`Natural`].
109    ///
110    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
111    /// \leq r < |y|$.
112    ///
113    /// $$
114    /// f(x, y) = x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
115    /// $$
116    ///
117    /// # Worst-case complexity
118    /// $T(n) = O(n \log n \log \log n)$
119    ///
120    /// $M(n) = O(n \log n)$
121    ///
122    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
123    ///
124    /// # Panics
125    /// Panics if `other` is zero.
126    ///
127    /// # Examples
128    /// ```
129    /// use malachite_base::num::arithmetic::traits::ModEuclidean;
130    /// use malachite_nz::integer::Integer;
131    ///
132    /// // -2 * -10 + 3 = 23
133    /// assert_eq!((&Integer::from(23)).mod_euclidean(Integer::from(-10)), 3);
134    /// ```
135    #[inline]
136    fn mod_euclidean(self, other: Integer) -> Natural {
137        let r = self.mod_op(&other);
138        if r < 0u32 {
139            (r - other).unsigned_abs()
140        } else {
141            r.unsigned_abs()
142        }
143    }
144}
145
146impl ModEuclidean<&Integer> for &Integer {
147    type Output = Natural;
148
149    /// Divides an [`Integer`] by another [`Integer`], taking both by reference and returning just
150    /// the remainder. The remainder is nonnegative and is returned as a [`Natural`].
151    ///
152    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
153    /// \leq r < |y|$.
154    ///
155    /// $$
156    /// f(x, y) = x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
157    /// $$
158    ///
159    /// # Worst-case complexity
160    /// $T(n) = O(n \log n \log \log n)$
161    ///
162    /// $M(n) = O(n \log n)$
163    ///
164    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
165    ///
166    /// # Panics
167    /// Panics if `other` is zero.
168    ///
169    /// # Examples
170    /// ```
171    /// use malachite_base::num::arithmetic::traits::ModEuclidean;
172    /// use malachite_nz::integer::Integer;
173    ///
174    /// // 3 * -10 + 7 = -23
175    /// assert_eq!((&Integer::from(-23)).mod_euclidean(&Integer::from(-10)), 7);
176    /// ```
177    #[inline]
178    fn mod_euclidean(self, other: &Integer) -> Natural {
179        let r = self.mod_op(other);
180        if r < 0u32 {
181            (r - other).unsigned_abs()
182        } else {
183            r.unsigned_abs()
184        }
185    }
186}
187
188impl ModEuclideanAssign<Self> for Integer {
189    /// Divides an [`Integer`] by another [`Integer`], taking the [`Integer`] on the right-hand side
190    /// by value and replacing the first [`Integer`] by the remainder. The remainder is nonnegative.
191    ///
192    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
193    /// \leq r < |y|$.
194    ///
195    /// $$
196    /// x \gets x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
197    /// $$
198    ///
199    /// # Worst-case complexity
200    /// $T(n) = O(n \log n \log \log n)$
201    ///
202    /// $M(n) = O(n \log n)$
203    ///
204    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
205    ///
206    /// # Panics
207    /// Panics if `other` is zero.
208    ///
209    /// # Examples
210    /// ```
211    /// use malachite_base::num::arithmetic::traits::ModEuclideanAssign;
212    /// use malachite_nz::integer::Integer;
213    ///
214    /// // -3 * 10 + 7 = -23
215    /// let mut x = Integer::from(-23);
216    /// x.mod_euclidean_assign(Integer::from(10));
217    /// assert_eq!(x, 7);
218    ///
219    /// // 3 * -10 + 7 = -23
220    /// let mut x = Integer::from(-23);
221    /// x.mod_euclidean_assign(Integer::from(-10));
222    /// assert_eq!(x, 7);
223    /// ```
224    #[inline]
225    fn mod_euclidean_assign(&mut self, other: Self) {
226        self.mod_assign(&other);
227        if *self < 0u32 {
228            *self -= other;
229        }
230    }
231}
232
233impl ModEuclideanAssign<&Self> for Integer {
234    /// Divides an [`Integer`] by another [`Integer`], taking the [`Integer`] on the right-hand side
235    /// by reference and replacing the first [`Integer`] by the remainder. The remainder is
236    /// nonnegative.
237    ///
238    /// If the quotient were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
239    /// \leq r < |y|$.
240    ///
241    /// $$
242    /// x \gets x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
243    /// $$
244    ///
245    /// # Worst-case complexity
246    /// $T(n) = O(n \log n \log \log n)$
247    ///
248    /// $M(n) = O(n \log n)$
249    ///
250    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
251    ///
252    /// # Panics
253    /// Panics if `other` is zero.
254    ///
255    /// # Examples
256    /// ```
257    /// use malachite_base::num::arithmetic::traits::ModEuclideanAssign;
258    /// use malachite_nz::integer::Integer;
259    ///
260    /// // 3 * -10 + 7 = -23
261    /// let mut x = Integer::from(-23);
262    /// x.mod_euclidean_assign(&Integer::from(-10));
263    /// assert_eq!(x, 7);
264    /// ```
265    #[inline]
266    fn mod_euclidean_assign(&mut self, other: &Self) {
267        self.mod_assign(other);
268        if *self < 0u32 {
269            *self -= other;
270        }
271    }
272}