malachite_nz/integer/arithmetic/div_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 DivAssignEuclidean, DivEuclidean, DivMod, UnsignedAbs,
13};
14use malachite_base::num::basic::traits::{One, Zero};
15
16// Adjusts the `(quotient, remainder)` returned by `div_mod` (whose remainder has the sign of the
17// divisor) into the Euclidean `(quotient, remainder)`, whose remainder is always nonnegative and is
18// therefore returned as a [`Natural`]. A negative remainder occurs only for a negative divisor;
19// adding the divisor's absolute value to the remainder and incrementing the quotient preserves $x =
20// qy + r$ while making $r$ nonnegative.
21fn make_remainder_nonnegative(q: Integer, r: Integer, other: Integer) -> (Integer, Natural) {
22 if r < Integer::ZERO {
23 (q + Integer::ONE, (r - other).unsigned_abs())
24 } else {
25 (q, r.unsigned_abs())
26 }
27}
28
29impl DivEuclidean<Self> for Integer {
30 type DivOutput = Self;
31 type ModOutput = Natural;
32
33 /// Divides an [`Integer`] by another [`Integer`], taking both by value and returning the
34 /// quotient and remainder. The quotient is rounded so that the remainder is nonnegative; the
35 /// remainder is returned as a [`Natural`].
36 ///
37 /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < |y|$.
38 ///
39 /// $$
40 /// f(x, y) = \left ( \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor, \space
41 /// x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor \right ).
42 /// $$
43 ///
44 /// # Worst-case complexity
45 /// $T(n) = O(n \log n \log \log n)$
46 ///
47 /// $M(n) = O(n \log n)$
48 ///
49 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
50 ///
51 /// # Panics
52 /// Panics if `other` is zero.
53 ///
54 /// # Examples
55 /// ```
56 /// use malachite_base::num::arithmetic::traits::DivEuclidean;
57 /// use malachite_base::strings::ToDebugString;
58 /// use malachite_nz::integer::Integer;
59 ///
60 /// // 2 * 10 + 3 = 23
61 /// assert_eq!(
62 /// Integer::from(23)
63 /// .div_euclidean(Integer::from(10))
64 /// .to_debug_string(),
65 /// "(2, 3)"
66 /// );
67 ///
68 /// // 3 * -10 + 7 = -23
69 /// assert_eq!(
70 /// Integer::from(-23)
71 /// .div_euclidean(Integer::from(-10))
72 /// .to_debug_string(),
73 /// "(3, 7)"
74 /// );
75 /// ```
76 #[inline]
77 fn div_euclidean(self, other: Self) -> (Self, Natural) {
78 let (q, r) = self.div_mod(&other);
79 make_remainder_nonnegative(q, r, other)
80 }
81}
82
83impl DivEuclidean<&Self> for Integer {
84 type DivOutput = Self;
85 type ModOutput = Natural;
86
87 /// Divides an [`Integer`] by another [`Integer`], taking the first by value and the second by
88 /// reference and returning the quotient and remainder. The quotient is rounded so that the
89 /// remainder is nonnegative; the remainder is returned as a [`Natural`].
90 ///
91 /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < |y|$.
92 ///
93 /// $$
94 /// f(x, y) = \left ( \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor, \space
95 /// x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor \right ).
96 /// $$
97 ///
98 /// # Worst-case complexity
99 /// $T(n) = O(n \log n \log \log n)$
100 ///
101 /// $M(n) = O(n \log n)$
102 ///
103 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
104 ///
105 /// # Panics
106 /// Panics if `other` is zero.
107 ///
108 /// # Examples
109 /// ```
110 /// use malachite_base::num::arithmetic::traits::DivEuclidean;
111 /// use malachite_base::strings::ToDebugString;
112 /// use malachite_nz::integer::Integer;
113 ///
114 /// // -3 * 10 + 7 = -23
115 /// assert_eq!(
116 /// Integer::from(-23)
117 /// .div_euclidean(&Integer::from(10))
118 /// .to_debug_string(),
119 /// "(-3, 7)"
120 /// );
121 /// ```
122 #[inline]
123 fn div_euclidean(self, other: &Self) -> (Self, Natural) {
124 let (q, r) = self.div_mod(other);
125 if r < Self::ZERO {
126 (q + Self::ONE, (r - other).unsigned_abs())
127 } else {
128 (q, r.unsigned_abs())
129 }
130 }
131}
132
133impl DivEuclidean<Integer> for &Integer {
134 type DivOutput = Integer;
135 type ModOutput = Natural;
136
137 /// Divides an [`Integer`] by another [`Integer`], taking the first by reference and the second
138 /// by value and returning the quotient and remainder. The quotient is rounded so that the
139 /// remainder is nonnegative; the remainder is returned as a [`Natural`].
140 ///
141 /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < |y|$.
142 ///
143 /// $$
144 /// f(x, y) = \left ( \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor, \space
145 /// x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor \right ).
146 /// $$
147 ///
148 /// # Worst-case complexity
149 /// $T(n) = O(n \log n \log \log n)$
150 ///
151 /// $M(n) = O(n \log n)$
152 ///
153 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
154 ///
155 /// # Panics
156 /// Panics if `other` is zero.
157 ///
158 /// # Examples
159 /// ```
160 /// use malachite_base::num::arithmetic::traits::DivEuclidean;
161 /// use malachite_base::strings::ToDebugString;
162 /// use malachite_nz::integer::Integer;
163 ///
164 /// // -2 * -10 + 3 = 23
165 /// assert_eq!(
166 /// (&Integer::from(23))
167 /// .div_euclidean(Integer::from(-10))
168 /// .to_debug_string(),
169 /// "(-2, 3)"
170 /// );
171 /// ```
172 #[inline]
173 fn div_euclidean(self, other: Integer) -> (Integer, Natural) {
174 let (q, r) = self.div_mod(&other);
175 make_remainder_nonnegative(q, r, other)
176 }
177}
178
179impl DivEuclidean<&Integer> for &Integer {
180 type DivOutput = Integer;
181 type ModOutput = Natural;
182
183 /// Divides an [`Integer`] by another [`Integer`], taking both by reference and returning the
184 /// quotient and remainder. The quotient is rounded so that the remainder is nonnegative; the
185 /// remainder is returned as a [`Natural`].
186 ///
187 /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < |y|$.
188 ///
189 /// $$
190 /// f(x, y) = \left ( \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor, \space
191 /// x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor \right ).
192 /// $$
193 ///
194 /// # Worst-case complexity
195 /// $T(n) = O(n \log n \log \log n)$
196 ///
197 /// $M(n) = O(n \log n)$
198 ///
199 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
200 ///
201 /// # Panics
202 /// Panics if `other` is zero.
203 ///
204 /// # Examples
205 /// ```
206 /// use malachite_base::num::arithmetic::traits::DivEuclidean;
207 /// use malachite_base::strings::ToDebugString;
208 /// use malachite_nz::integer::Integer;
209 ///
210 /// // 3 * -10 + 7 = -23
211 /// assert_eq!(
212 /// (&Integer::from(-23))
213 /// .div_euclidean(&Integer::from(-10))
214 /// .to_debug_string(),
215 /// "(3, 7)"
216 /// );
217 /// ```
218 #[inline]
219 fn div_euclidean(self, other: &Integer) -> (Integer, Natural) {
220 let (q, r) = self.div_mod(other);
221 if r < Integer::ZERO {
222 (q + Integer::ONE, (r - other).unsigned_abs())
223 } else {
224 (q, r.unsigned_abs())
225 }
226 }
227}
228
229impl DivAssignEuclidean<Self> for Integer {
230 type ModOutput = Natural;
231
232 /// Divides an [`Integer`] by another [`Integer`] in place, taking the [`Integer`] on the
233 /// right-hand side by value and returning the remainder. The quotient is rounded so that the
234 /// remainder is nonnegative.
235 ///
236 /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < |y|$.
237 ///
238 /// $$
239 /// f(x, y) = x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor,
240 /// $$
241 /// $$
242 /// x \gets \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::DivAssignEuclidean;
258 /// use malachite_nz::integer::Integer;
259 ///
260 /// // -3 * 10 + 7 = -23
261 /// let mut x = Integer::from(-23);
262 /// assert_eq!(x.div_assign_euclidean(Integer::from(10)), 7);
263 /// assert_eq!(x, -3);
264 /// ```
265 #[inline]
266 fn div_assign_euclidean(&mut self, other: Self) -> Natural {
267 let (q, r) = (&*self).div_euclidean(other);
268 *self = q;
269 r
270 }
271}
272
273impl DivAssignEuclidean<&Self> for Integer {
274 type ModOutput = Natural;
275
276 /// Divides an [`Integer`] by another [`Integer`] in place, taking the [`Integer`] on the
277 /// right-hand side by reference and returning the remainder. The quotient is rounded so that
278 /// the remainder is nonnegative.
279 ///
280 /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < |y|$.
281 ///
282 /// $$
283 /// f(x, y) = x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor,
284 /// $$
285 /// $$
286 /// x \gets \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
287 /// $$
288 ///
289 /// # Worst-case complexity
290 /// $T(n) = O(n \log n \log \log n)$
291 ///
292 /// $M(n) = O(n \log n)$
293 ///
294 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
295 ///
296 /// # Panics
297 /// Panics if `other` is zero.
298 ///
299 /// # Examples
300 /// ```
301 /// use malachite_base::num::arithmetic::traits::DivAssignEuclidean;
302 /// use malachite_nz::integer::Integer;
303 ///
304 /// // 3 * -10 + 7 = -23
305 /// let mut x = Integer::from(-23);
306 /// assert_eq!(x.div_assign_euclidean(&Integer::from(-10)), 7);
307 /// assert_eq!(x, 3);
308 /// ```
309 #[inline]
310 fn div_assign_euclidean(&mut self, other: &Self) -> Natural {
311 let (q, r) = (&*self).div_euclidean(other);
312 *self = q;
313 r
314 }
315}