Skip to main content

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}