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 malachite_base::num::arithmetic::traits::{
11 DivEuclidean, DivEuclideanAssign, DivRound, DivRoundAssign,
12};
13use malachite_base::rounding_modes::RoundingMode::{Ceiling, Floor};
14
15impl DivEuclidean<Self> for Integer {
16 type Output = Self;
17
18 /// Divides an [`Integer`] by another [`Integer`], taking both by value and returning just the
19 /// quotient. The quotient is rounded so that the remainder would be nonnegative.
20 ///
21 /// If the remainder were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
22 /// \leq r < |y|$.
23 ///
24 /// $$
25 /// f(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::DivEuclidean;
41 /// use malachite_nz::integer::Integer;
42 ///
43 /// // 2 * 10 + 3 = 23
44 /// assert_eq!(Integer::from(23).div_euclidean(Integer::from(10)), 2);
45 ///
46 /// // 3 * -10 + 7 = -23
47 /// assert_eq!(Integer::from(-23).div_euclidean(Integer::from(-10)), 3);
48 /// ```
49 #[inline]
50 fn div_euclidean(self, other: Self) -> Self {
51 let rm = if other > 0u32 { Floor } else { Ceiling };
52 self.div_round(other, rm).0
53 }
54}
55
56impl DivEuclidean<&Self> for Integer {
57 type Output = Self;
58
59 /// Divides an [`Integer`] by another [`Integer`], taking the first by value and the second by
60 /// reference and returning just the quotient. The quotient is rounded so that the remainder
61 /// would be nonnegative.
62 ///
63 /// If the remainder were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
64 /// \leq r < |y|$.
65 ///
66 /// $$
67 /// f(x, y) = \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
68 /// $$
69 ///
70 /// # Worst-case complexity
71 /// $T(n) = O(n \log n \log \log n)$
72 ///
73 /// $M(n) = O(n \log n)$
74 ///
75 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
76 ///
77 /// # Panics
78 /// Panics if `other` is zero.
79 ///
80 /// # Examples
81 /// ```
82 /// use malachite_base::num::arithmetic::traits::DivEuclidean;
83 /// use malachite_nz::integer::Integer;
84 ///
85 /// // -3 * 10 + 7 = -23
86 /// assert_eq!(Integer::from(-23).div_euclidean(&Integer::from(10)), -3);
87 /// ```
88 #[inline]
89 fn div_euclidean(self, other: &Self) -> Self {
90 let rm = if *other > 0u32 { Floor } else { Ceiling };
91 self.div_round(other, rm).0
92 }
93}
94
95impl DivEuclidean<Integer> for &Integer {
96 type Output = Integer;
97
98 /// Divides an [`Integer`] by another [`Integer`], taking the first by reference and the second
99 /// by value and returning just the quotient. The quotient is rounded so that the remainder
100 /// would be nonnegative.
101 ///
102 /// If the remainder were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
103 /// \leq r < |y|$.
104 ///
105 /// $$
106 /// f(x, y) = \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
107 /// $$
108 ///
109 /// # Worst-case complexity
110 /// $T(n) = O(n \log n \log \log n)$
111 ///
112 /// $M(n) = O(n \log n)$
113 ///
114 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
115 ///
116 /// # Panics
117 /// Panics if `other` is zero.
118 ///
119 /// # Examples
120 /// ```
121 /// use malachite_base::num::arithmetic::traits::DivEuclidean;
122 /// use malachite_nz::integer::Integer;
123 ///
124 /// // -2 * -10 + 3 = 23
125 /// assert_eq!((&Integer::from(23)).div_euclidean(Integer::from(-10)), -2);
126 /// ```
127 #[inline]
128 fn div_euclidean(self, other: Integer) -> Integer {
129 let rm = if other > 0u32 { Floor } else { Ceiling };
130 self.div_round(other, rm).0
131 }
132}
133
134impl DivEuclidean<&Integer> for &Integer {
135 type Output = Integer;
136
137 /// Divides an [`Integer`] by another [`Integer`], taking both by reference and returning just
138 /// the quotient. The quotient is rounded so that the remainder would be nonnegative.
139 ///
140 /// If the remainder were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
141 /// \leq r < |y|$.
142 ///
143 /// $$
144 /// f(x, y) = \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
145 /// $$
146 ///
147 /// # Worst-case complexity
148 /// $T(n) = O(n \log n \log \log n)$
149 ///
150 /// $M(n) = O(n \log n)$
151 ///
152 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
153 ///
154 /// # Panics
155 /// Panics if `other` is zero.
156 ///
157 /// # Examples
158 /// ```
159 /// use malachite_base::num::arithmetic::traits::DivEuclidean;
160 /// use malachite_nz::integer::Integer;
161 ///
162 /// // 3 * -10 + 7 = -23
163 /// assert_eq!((&Integer::from(-23)).div_euclidean(&Integer::from(-10)), 3);
164 /// ```
165 #[inline]
166 fn div_euclidean(self, other: &Integer) -> Integer {
167 let rm = if *other > 0u32 { Floor } else { Ceiling };
168 self.div_round(other, rm).0
169 }
170}
171
172impl DivEuclideanAssign<Self> for Integer {
173 /// Divides an [`Integer`] by another [`Integer`] in place, taking the [`Integer`] on the
174 /// right-hand side by value and keeping just the quotient. The quotient is rounded so that the
175 /// remainder would be nonnegative.
176 ///
177 /// If the remainder were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
178 /// \leq r < |y|$.
179 ///
180 /// $$
181 /// x \gets \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
182 /// $$
183 ///
184 /// # Worst-case complexity
185 /// $T(n) = O(n \log n \log \log n)$
186 ///
187 /// $M(n) = O(n \log n)$
188 ///
189 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
190 ///
191 /// # Panics
192 /// Panics if `other` is zero.
193 ///
194 /// # Examples
195 /// ```
196 /// use malachite_base::num::arithmetic::traits::DivEuclideanAssign;
197 /// use malachite_nz::integer::Integer;
198 ///
199 /// // -3 * 10 + 7 = -23
200 /// let mut x = Integer::from(-23);
201 /// x.div_euclidean_assign(Integer::from(10));
202 /// assert_eq!(x, -3);
203 /// ```
204 #[inline]
205 fn div_euclidean_assign(&mut self, other: Self) {
206 let rm = if other > 0u32 { Floor } else { Ceiling };
207 self.div_round_assign(other, rm);
208 }
209}
210
211impl DivEuclideanAssign<&Self> for Integer {
212 /// Divides an [`Integer`] by another [`Integer`] in place, taking the [`Integer`] on the
213 /// right-hand side by reference and keeping just the quotient. The quotient is rounded so that
214 /// the remainder would be nonnegative.
215 ///
216 /// If the remainder were computed, the quotient and remainder would satisfy $x = qy + r$ and $0
217 /// \leq r < |y|$.
218 ///
219 /// $$
220 /// x \gets \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
221 /// $$
222 ///
223 /// # Worst-case complexity
224 /// $T(n) = O(n \log n \log \log n)$
225 ///
226 /// $M(n) = O(n \log n)$
227 ///
228 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
229 ///
230 /// # Panics
231 /// Panics if `other` is zero.
232 ///
233 /// # Examples
234 /// ```
235 /// use malachite_base::num::arithmetic::traits::DivEuclideanAssign;
236 /// use malachite_nz::integer::Integer;
237 ///
238 /// // 3 * -10 + 7 = -23
239 /// let mut x = Integer::from(-23);
240 /// x.div_euclidean_assign(&Integer::from(-10));
241 /// assert_eq!(x, 3);
242 /// ```
243 #[inline]
244 fn div_euclidean_assign(&mut self, other: &Self) {
245 let rm = if *other > 0u32 { Floor } else { Ceiling };
246 self.div_round_assign(other, rm);
247 }
248}