malachite_nz/integer/arithmetic/div_round.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 core::cmp::Ordering;
11use malachite_base::num::arithmetic::traits::{DivRound, DivRoundAssign};
12use malachite_base::rounding_modes::RoundingMode;
13
14impl DivRound<Self> for Integer {
15 type Output = Self;
16
17 /// Divides an [`Integer`] by another [`Integer`], taking both by value and rounding according
18 /// to a specified rounding mode. An [`Ordering`] is also returned, indicating whether the
19 /// returned value is less than, equal to, or greater than the exact value.
20 ///
21 /// Let $q = \frac{x}{y}$, and let $g$ be the function that just returns the first element of
22 /// the pair, without the [`Ordering`]:
23 ///
24 /// $$
25 /// g(x, y, \mathrm{Down}) = \operatorname{sgn}(q) \lfloor |q| \rfloor.
26 /// $$
27 ///
28 /// $$
29 /// g(x, y, \mathrm{Up}) = \operatorname{sgn}(q) \lceil |q| \rceil.
30 /// $$
31 ///
32 /// $$
33 /// g(x, y, \mathrm{Floor}) = \lfloor q \rfloor.
34 /// $$
35 ///
36 /// $$
37 /// g(x, y, \mathrm{Ceiling}) = \lceil q \rceil.
38 /// $$
39 ///
40 /// $$
41 /// g(x, y, \mathrm{Nearest}) = \begin{cases}
42 /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\
43 /// \lceil q \rceil & q - \lfloor q \rfloor > \frac{1}{2}, \\\\
44 /// \lfloor q \rfloor &
45 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
46 /// \\ \lfloor q \rfloor \\ \text{is even}, \\\\
47 /// \lceil q \rceil &
48 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
49 /// \\ \lfloor q \rfloor \\ \text{is odd.}
50 /// \end{cases}
51 /// $$
52 ///
53 /// $g(x, y, \mathrm{Exact}) = q$, but panics if $q \notin \Z$.
54 ///
55 /// Then $f(x, y, r) = (g(x, y, r), \operatorname{cmp}(g(x, y, r), q))$.
56 ///
57 /// # Worst-case complexity
58 /// $T(n) = O(n \log n \log \log n)$
59 ///
60 /// $M(n) = O(n \log n)$
61 ///
62 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
63 ///
64 /// # Panics
65 /// Panics if `other` is zero, or if `rm` is `Exact` but `self` is not divisible by `other`.
66 ///
67 /// # Examples
68 /// ```
69 /// use core::cmp::Ordering::*;
70 /// use malachite_base::num::arithmetic::traits::{DivRound, Pow};
71 /// use malachite_base::num::basic::traits::Two;
72 /// use malachite_base::rounding_modes::RoundingMode::*;
73 /// use malachite_nz::integer::Integer;
74 ///
75 /// assert_eq!(
76 /// Integer::from(-10).div_round(Integer::from(4), Down),
77 /// (Integer::from(-2), Greater)
78 /// );
79 /// assert_eq!(
80 /// (-Integer::from(10u32).pow(12)).div_round(Integer::from(3), Floor),
81 /// (Integer::from(-333333333334i64), Less)
82 /// );
83 /// assert_eq!(
84 /// Integer::from(-10).div_round(Integer::from(4), Up),
85 /// (Integer::from(-3), Less)
86 /// );
87 /// assert_eq!(
88 /// (-Integer::from(10u32).pow(12)).div_round(Integer::from(3), Ceiling),
89 /// (Integer::from(-333333333333i64), Greater)
90 /// );
91 /// assert_eq!(
92 /// Integer::from(-10).div_round(Integer::from(5), Exact),
93 /// (Integer::from(-2), Equal)
94 /// );
95 /// assert_eq!(
96 /// Integer::from(-10).div_round(Integer::from(3), Nearest),
97 /// (Integer::from(-3), Greater)
98 /// );
99 /// assert_eq!(
100 /// Integer::from(-20).div_round(Integer::from(3), Nearest),
101 /// (Integer::from(-7), Less)
102 /// );
103 /// assert_eq!(
104 /// Integer::from(-10).div_round(Integer::from(4), Nearest),
105 /// (Integer::from(-2), Greater)
106 /// );
107 /// assert_eq!(
108 /// Integer::from(-14).div_round(Integer::from(4), Nearest),
109 /// (Integer::from(-4), Less)
110 /// );
111 ///
112 /// assert_eq!(
113 /// Integer::from(-10).div_round(Integer::from(-4), Down),
114 /// (Integer::TWO, Less)
115 /// );
116 /// assert_eq!(
117 /// (-Integer::from(10u32).pow(12)).div_round(Integer::from(-3), Floor),
118 /// (Integer::from(333333333333i64), Less)
119 /// );
120 /// assert_eq!(
121 /// Integer::from(-10).div_round(Integer::from(-4), Up),
122 /// (Integer::from(3), Greater)
123 /// );
124 /// assert_eq!(
125 /// (-Integer::from(10u32).pow(12)).div_round(Integer::from(-3), Ceiling),
126 /// (Integer::from(333333333334i64), Greater)
127 /// );
128 /// assert_eq!(
129 /// Integer::from(-10).div_round(Integer::from(-5), Exact),
130 /// (Integer::TWO, Equal)
131 /// );
132 /// assert_eq!(
133 /// Integer::from(-10).div_round(Integer::from(-3), Nearest),
134 /// (Integer::from(3), Less)
135 /// );
136 /// assert_eq!(
137 /// Integer::from(-20).div_round(Integer::from(-3), Nearest),
138 /// (Integer::from(7), Greater)
139 /// );
140 /// assert_eq!(
141 /// Integer::from(-10).div_round(Integer::from(-4), Nearest),
142 /// (Integer::TWO, Less)
143 /// );
144 /// assert_eq!(
145 /// Integer::from(-14).div_round(Integer::from(-4), Nearest),
146 /// (Integer::from(4), Greater)
147 /// );
148 /// ```
149 #[inline]
150 fn div_round(mut self, other: Self, rm: RoundingMode) -> (Self, Ordering) {
151 let o = self.div_round_assign(other, rm);
152 (self, o)
153 }
154}
155
156impl DivRound<&Self> for Integer {
157 type Output = Self;
158
159 /// Divides an [`Integer`] by another [`Integer`], taking the first by value and the second by
160 /// reference and rounding according to a specified rounding mode. An [`Ordering`] is also
161 /// returned, indicating whether the returned value is less than, equal to, or greater than the
162 /// exact value.
163 ///
164 /// Let $q = \frac{x}{y}$, and let $g$ be the function that just returns the first element of
165 /// the pair, without the [`Ordering`]:
166 ///
167 /// $$
168 /// g(x, y, \mathrm{Down}) = \operatorname{sgn}(q) \lfloor |q| \rfloor.
169 /// $$
170 ///
171 /// $$
172 /// g(x, y, \mathrm{Up}) = \operatorname{sgn}(q) \lceil |q| \rceil.
173 /// $$
174 ///
175 /// $$
176 /// g(x, y, \mathrm{Floor}) = \lfloor q \rfloor.
177 /// $$
178 ///
179 /// $$
180 /// g(x, y, \mathrm{Ceiling}) = \lceil q \rceil.
181 /// $$
182 ///
183 /// $$
184 /// g(x, y, \mathrm{Nearest}) = \begin{cases}
185 /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\
186 /// \lceil q \rceil & q - \lfloor q \rfloor > \frac{1}{2}, \\\\
187 /// \lfloor q \rfloor &
188 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
189 /// \\ \lfloor q \rfloor \\ \text{is even}, \\\\
190 /// \lceil q \rceil &
191 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
192 /// \\ \lfloor q \rfloor \\ \text{is odd.}
193 /// \end{cases}
194 /// $$
195 ///
196 /// $g(x, y, \mathrm{Exact}) = q$, but panics if $q \notin \Z$.
197 ///
198 /// Then $f(x, y, r) = (g(x, y, r), \operatorname{cmp}(g(x, y, r), q))$.
199 ///
200 /// # Worst-case complexity
201 /// $T(n) = O(n \log n \log \log n)$
202 ///
203 /// $M(n) = O(n \log n)$
204 ///
205 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
206 ///
207 /// # Panics
208 /// Panics if `other` is zero, or if `rm` is `Exact` but `self` is not divisible by `other`.
209 ///
210 /// # Examples
211 /// ```
212 /// use core::cmp::Ordering::*;
213 /// use malachite_base::num::arithmetic::traits::{DivRound, Pow};
214 /// use malachite_base::num::basic::traits::Two;
215 /// use malachite_base::rounding_modes::RoundingMode::*;
216 /// use malachite_nz::integer::Integer;
217 ///
218 /// assert_eq!(
219 /// Integer::from(-10).div_round(&Integer::from(4), Down),
220 /// (Integer::from(-2), Greater)
221 /// );
222 /// assert_eq!(
223 /// (-Integer::from(10u32).pow(12)).div_round(&Integer::from(3), Floor),
224 /// (Integer::from(-333333333334i64), Less)
225 /// );
226 /// assert_eq!(
227 /// Integer::from(-10).div_round(&Integer::from(4), Up),
228 /// (Integer::from(-3), Less)
229 /// );
230 /// assert_eq!(
231 /// (-Integer::from(10u32).pow(12)).div_round(&Integer::from(3), Ceiling),
232 /// (Integer::from(-333333333333i64), Greater)
233 /// );
234 /// assert_eq!(
235 /// Integer::from(-10).div_round(&Integer::from(5), Exact),
236 /// (Integer::from(-2), Equal)
237 /// );
238 /// assert_eq!(
239 /// Integer::from(-10).div_round(&Integer::from(3), Nearest),
240 /// (Integer::from(-3), Greater)
241 /// );
242 /// assert_eq!(
243 /// Integer::from(-20).div_round(&Integer::from(3), Nearest),
244 /// (Integer::from(-7), Less)
245 /// );
246 /// assert_eq!(
247 /// Integer::from(-10).div_round(&Integer::from(4), Nearest),
248 /// (Integer::from(-2), Greater)
249 /// );
250 /// assert_eq!(
251 /// Integer::from(-14).div_round(&Integer::from(4), Nearest),
252 /// (Integer::from(-4), Less)
253 /// );
254 ///
255 /// assert_eq!(
256 /// Integer::from(-10).div_round(&Integer::from(-4), Down),
257 /// (Integer::TWO, Less)
258 /// );
259 /// assert_eq!(
260 /// (-Integer::from(10u32).pow(12)).div_round(&Integer::from(-3), Floor),
261 /// (Integer::from(333333333333i64), Less)
262 /// );
263 /// assert_eq!(
264 /// Integer::from(-10).div_round(&Integer::from(-4), Up),
265 /// (Integer::from(3), Greater)
266 /// );
267 /// assert_eq!(
268 /// (-Integer::from(10u32).pow(12)).div_round(&Integer::from(-3), Ceiling),
269 /// (Integer::from(333333333334i64), Greater)
270 /// );
271 /// assert_eq!(
272 /// Integer::from(-10).div_round(&Integer::from(-5), Exact),
273 /// (Integer::TWO, Equal)
274 /// );
275 /// assert_eq!(
276 /// Integer::from(-10).div_round(&Integer::from(-3), Nearest),
277 /// (Integer::from(3), Less)
278 /// );
279 /// assert_eq!(
280 /// Integer::from(-20).div_round(&Integer::from(-3), Nearest),
281 /// (Integer::from(7), Greater)
282 /// );
283 /// assert_eq!(
284 /// Integer::from(-10).div_round(&Integer::from(-4), Nearest),
285 /// (Integer::TWO, Less)
286 /// );
287 /// assert_eq!(
288 /// Integer::from(-14).div_round(&Integer::from(-4), Nearest),
289 /// (Integer::from(4), Greater)
290 /// );
291 /// ```
292 #[inline]
293 fn div_round(mut self, other: &Self, rm: RoundingMode) -> (Self, Ordering) {
294 let o = self.div_round_assign(other, rm);
295 (self, o)
296 }
297}
298
299impl DivRound<Integer> for &Integer {
300 type Output = Integer;
301
302 /// Divides an [`Integer`] by another [`Integer`], taking the first by reference and the second
303 /// by value and rounding according to a specified rounding mode. An [`Ordering`] is also
304 /// returned, indicating whether the returned value is less than, equal to, or greater than the
305 /// exact value.
306 ///
307 /// Let $q = \frac{x}{y}$, and let $g$ be the function that just returns the first element of
308 /// the pair, without the [`Ordering`]:
309 ///
310 /// $$
311 /// g(x, y, \mathrm{Down}) = \operatorname{sgn}(q) \lfloor |q| \rfloor.
312 /// $$
313 ///
314 /// $$
315 /// g(x, y, \mathrm{Up}) = \operatorname{sgn}(q) \lceil |q| \rceil.
316 /// $$
317 ///
318 /// $$
319 /// g(x, y, \mathrm{Floor}) = \lfloor q \rfloor.
320 /// $$
321 ///
322 /// $$
323 /// g(x, y, \mathrm{Ceiling}) = \lceil q \rceil.
324 /// $$
325 ///
326 /// $$
327 /// g(x, y, \mathrm{Nearest}) = \begin{cases}
328 /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\
329 /// \lceil q \rceil & q - \lfloor q \rfloor > \frac{1}{2}, \\\\
330 /// \lfloor q \rfloor &
331 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
332 /// \\ \lfloor q \rfloor \\ \text{is even}, \\\\
333 /// \lceil q \rceil &
334 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
335 /// \\ \lfloor q \rfloor \\ \text{is odd.}
336 /// \end{cases}
337 /// $$
338 ///
339 /// $g(x, y, \mathrm{Exact}) = q$, but panics if $q \notin \Z$.
340 ///
341 /// Then $f(x, y, r) = (g(x, y, r), \operatorname{cmp}(g(x, y, r), q))$.
342 ///
343 /// # Worst-case complexity
344 /// $T(n) = O(n \log n \log \log n)$
345 ///
346 /// $M(n) = O(n \log n)$
347 ///
348 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
349 ///
350 /// # Panics
351 /// Panics if `other` is zero, or if `rm` is `Exact` but `self` is not divisible by `other`.
352 ///
353 /// # Examples
354 /// ```
355 /// use core::cmp::Ordering::*;
356 /// use malachite_base::num::arithmetic::traits::{DivRound, Pow};
357 /// use malachite_base::num::basic::traits::Two;
358 /// use malachite_base::rounding_modes::RoundingMode::*;
359 /// use malachite_nz::integer::Integer;
360 ///
361 /// assert_eq!(
362 /// (&Integer::from(-10)).div_round(Integer::from(4), Down),
363 /// (Integer::from(-2), Greater)
364 /// );
365 /// assert_eq!(
366 /// (&-Integer::from(10u32).pow(12)).div_round(Integer::from(3), Floor),
367 /// (Integer::from(-333333333334i64), Less)
368 /// );
369 /// assert_eq!(
370 /// Integer::from(-10).div_round(Integer::from(4), Up),
371 /// (Integer::from(-3), Less)
372 /// );
373 /// assert_eq!(
374 /// (&-Integer::from(10u32).pow(12)).div_round(Integer::from(3), Ceiling),
375 /// (Integer::from(-333333333333i64), Greater)
376 /// );
377 /// assert_eq!(
378 /// (&Integer::from(-10)).div_round(Integer::from(5), Exact),
379 /// (Integer::from(-2), Equal)
380 /// );
381 /// assert_eq!(
382 /// (&Integer::from(-10)).div_round(Integer::from(3), Nearest),
383 /// (Integer::from(-3), Greater)
384 /// );
385 /// assert_eq!(
386 /// (&Integer::from(-20)).div_round(Integer::from(3), Nearest),
387 /// (Integer::from(-7), Less)
388 /// );
389 /// assert_eq!(
390 /// (&Integer::from(-10)).div_round(Integer::from(4), Nearest),
391 /// (Integer::from(-2), Greater)
392 /// );
393 /// assert_eq!(
394 /// (&Integer::from(-14)).div_round(Integer::from(4), Nearest),
395 /// (Integer::from(-4), Less)
396 /// );
397 ///
398 /// assert_eq!(
399 /// (&Integer::from(-10)).div_round(Integer::from(-4), Down),
400 /// (Integer::TWO, Less)
401 /// );
402 /// assert_eq!(
403 /// (&-Integer::from(10u32).pow(12)).div_round(Integer::from(-3), Floor),
404 /// (Integer::from(333333333333i64), Less)
405 /// );
406 /// assert_eq!(
407 /// (&Integer::from(-10)).div_round(Integer::from(-4), Up),
408 /// (Integer::from(3), Greater)
409 /// );
410 /// assert_eq!(
411 /// (&-Integer::from(10u32).pow(12)).div_round(Integer::from(-3), Ceiling),
412 /// (Integer::from(333333333334i64), Greater)
413 /// );
414 /// assert_eq!(
415 /// (&Integer::from(-10)).div_round(Integer::from(-5), Exact),
416 /// (Integer::TWO, Equal)
417 /// );
418 /// assert_eq!(
419 /// (&Integer::from(-10)).div_round(Integer::from(-3), Nearest),
420 /// (Integer::from(3), Less)
421 /// );
422 /// assert_eq!(
423 /// (&Integer::from(-20)).div_round(Integer::from(-3), Nearest),
424 /// (Integer::from(7), Greater)
425 /// );
426 /// assert_eq!(
427 /// (&Integer::from(-10)).div_round(Integer::from(-4), Nearest),
428 /// (Integer::TWO, Less)
429 /// );
430 /// assert_eq!(
431 /// (&Integer::from(-14)).div_round(Integer::from(-4), Nearest),
432 /// (Integer::from(4), Greater)
433 /// );
434 /// ```
435 fn div_round(self, other: Integer, rm: RoundingMode) -> (Integer, Ordering) {
436 let q_sign = self.sign == other.sign;
437 let (q_abs, o) = (&self.abs).div_round(other.abs, if q_sign { rm } else { -rm });
438 (
439 Integer::from_sign_and_abs(q_sign, q_abs),
440 if q_sign { o } else { o.reverse() },
441 )
442 }
443}
444
445impl DivRound<&Integer> for &Integer {
446 type Output = Integer;
447
448 /// Divides an [`Integer`] by another [`Integer`], taking both by reference and rounding
449 /// according to a specified rounding mode. An [`Ordering`] is also returned, indicating whether
450 /// the returned value is less than, equal to, or greater than the exact value.
451 ///
452 /// Let $q = \frac{x}{y}$, and let $g$ be the function that just returns the first element of
453 /// the pair, without the [`Ordering`]:
454 ///
455 /// $$
456 /// g(x, y, \mathrm{Down}) = \operatorname{sgn}(q) \lfloor |q| \rfloor.
457 /// $$
458 ///
459 /// $$
460 /// g(x, y, \mathrm{Up}) = \operatorname{sgn}(q) \lceil |q| \rceil.
461 /// $$
462 ///
463 /// $$
464 /// g(x, y, \mathrm{Floor}) = \lfloor q \rfloor.
465 /// $$
466 ///
467 /// $$
468 /// g(x, y, \mathrm{Ceiling}) = \lceil q \rceil.
469 /// $$
470 ///
471 /// $$
472 /// g(x, y, \mathrm{Nearest}) = \begin{cases}
473 /// \lfloor q \rfloor & \text{if} \\quad q - \lfloor q \rfloor < \frac{1}{2}, \\\\
474 /// \lceil q \rceil & q - \lfloor q \rfloor > \frac{1}{2}, \\\\
475 /// \lfloor q \rfloor &
476 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
477 /// \\ \lfloor q \rfloor \\ \text{is even}, \\\\
478 /// \lceil q \rceil &
479 /// \text{if} \\quad q - \lfloor q \rfloor = \frac{1}{2} \\ \text{and}
480 /// \\ \lfloor q \rfloor \\ \text{is odd.}
481 /// \end{cases}
482 /// $$
483 ///
484 /// $g(x, y, \mathrm{Exact}) = q$, but panics if $q \notin \Z$.
485 ///
486 /// Then $f(x, y, r) = (g(x, y, r), \operatorname{cmp}(g(x, y, r), q))$.
487 ///
488 /// # Worst-case complexity
489 /// $T(n) = O(n \log n \log \log n)$
490 ///
491 /// $M(n) = O(n \log n)$
492 ///
493 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
494 ///
495 /// # Panics
496 /// Panics if `other` is zero, or if `rm` is `Exact` but `self` is not divisible by `other`.
497 ///
498 /// # Examples
499 /// ```
500 /// use core::cmp::Ordering::*;
501 /// use malachite_base::num::arithmetic::traits::{DivRound, Pow};
502 /// use malachite_base::num::basic::traits::Two;
503 /// use malachite_base::rounding_modes::RoundingMode::*;
504 /// use malachite_nz::integer::Integer;
505 ///
506 /// assert_eq!(
507 /// (&Integer::from(-10)).div_round(&Integer::from(4), Down),
508 /// (Integer::from(-2), Greater)
509 /// );
510 /// assert_eq!(
511 /// (&-Integer::from(10u32).pow(12)).div_round(&Integer::from(3), Floor),
512 /// (Integer::from(-333333333334i64), Less)
513 /// );
514 /// assert_eq!(
515 /// Integer::from(-10).div_round(&Integer::from(4), Up),
516 /// (Integer::from(-3), Less)
517 /// );
518 /// assert_eq!(
519 /// (&-Integer::from(10u32).pow(12)).div_round(&Integer::from(3), Ceiling),
520 /// (Integer::from(-333333333333i64), Greater)
521 /// );
522 /// assert_eq!(
523 /// (&Integer::from(-10)).div_round(&Integer::from(5), Exact),
524 /// (Integer::from(-2), Equal)
525 /// );
526 /// assert_eq!(
527 /// (&Integer::from(-10)).div_round(&Integer::from(3), Nearest),
528 /// (Integer::from(-3), Greater)
529 /// );
530 /// assert_eq!(
531 /// (&Integer::from(-20)).div_round(&Integer::from(3), Nearest),
532 /// (Integer::from(-7), Less)
533 /// );
534 /// assert_eq!(
535 /// (&Integer::from(-10)).div_round(&Integer::from(4), Nearest),
536 /// (Integer::from(-2), Greater)
537 /// );
538 /// assert_eq!(
539 /// (&Integer::from(-14)).div_round(&Integer::from(4), Nearest),
540 /// (Integer::from(-4), Less)
541 /// );
542 ///
543 /// assert_eq!(
544 /// (&Integer::from(-10)).div_round(&Integer::from(-4), Down),
545 /// (Integer::TWO, Less)
546 /// );
547 /// assert_eq!(
548 /// (&-Integer::from(10u32).pow(12)).div_round(&Integer::from(-3), Floor),
549 /// (Integer::from(333333333333i64), Less)
550 /// );
551 /// assert_eq!(
552 /// (&Integer::from(-10)).div_round(&Integer::from(-4), Up),
553 /// (Integer::from(3), Greater)
554 /// );
555 /// assert_eq!(
556 /// (&-Integer::from(10u32).pow(12)).div_round(&Integer::from(-3), Ceiling),
557 /// (Integer::from(333333333334i64), Greater)
558 /// );
559 /// assert_eq!(
560 /// (&Integer::from(-10)).div_round(&Integer::from(-5), Exact),
561 /// (Integer::TWO, Equal)
562 /// );
563 /// assert_eq!(
564 /// (&Integer::from(-10)).div_round(&Integer::from(-3), Nearest),
565 /// (Integer::from(3), Less)
566 /// );
567 /// assert_eq!(
568 /// (&Integer::from(-20)).div_round(&Integer::from(-3), Nearest),
569 /// (Integer::from(7), Greater)
570 /// );
571 /// assert_eq!(
572 /// (&Integer::from(-10)).div_round(&Integer::from(-4), Nearest),
573 /// (Integer::TWO, Less)
574 /// );
575 /// assert_eq!(
576 /// (&Integer::from(-14)).div_round(&Integer::from(-4), Nearest),
577 /// (Integer::from(4), Greater)
578 /// );
579 /// ```
580 fn div_round(self, other: &Integer, rm: RoundingMode) -> (Integer, Ordering) {
581 let q_sign = self.sign == other.sign;
582 let (q_abs, o) = (&self.abs).div_round(&other.abs, if q_sign { rm } else { -rm });
583 (
584 Integer::from_sign_and_abs(q_sign, q_abs),
585 if q_sign { o } else { o.reverse() },
586 )
587 }
588}
589
590impl DivRoundAssign<Self> for Integer {
591 /// Divides an [`Integer`] by another [`Integer`] in place, taking the [`Integer`] on the
592 /// right-hand side by value and rounding according to a specified rounding mode. An
593 /// [`Ordering`] is returned, indicating whether the assigned value is less than, equal to, or
594 /// greater than the exact value.
595 ///
596 /// See the [`DivRound`] documentation for details.
597 ///
598 /// # Worst-case complexity
599 /// $T(n) = O(n \log n \log \log n)$
600 ///
601 /// $M(n) = O(n \log n)$
602 ///
603 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
604 ///
605 /// # Panics
606 /// Panics if `other` is zero, or if `rm` is `Exact` but `self` is not divisible by `other`.
607 ///
608 /// # Examples
609 /// ```
610 /// use core::cmp::Ordering::*;
611 /// use malachite_base::num::arithmetic::traits::{DivRoundAssign, Pow};
612 /// use malachite_base::rounding_modes::RoundingMode::*;
613 /// use malachite_nz::integer::Integer;
614 ///
615 /// let mut n = Integer::from(-10);
616 /// assert_eq!(n.div_round_assign(Integer::from(4), Down), Greater);
617 /// assert_eq!(n, -2);
618 ///
619 /// let mut n = -Integer::from(10u32).pow(12);
620 /// assert_eq!(n.div_round_assign(Integer::from(3), Floor), Less);
621 /// assert_eq!(n, -333333333334i64);
622 ///
623 /// let mut n = Integer::from(-10);
624 /// assert_eq!(n.div_round_assign(Integer::from(4), Up), Less);
625 /// assert_eq!(n, -3);
626 ///
627 /// let mut n = -Integer::from(10u32).pow(12);
628 /// assert_eq!(n.div_round_assign(Integer::from(3), Ceiling), Greater);
629 /// assert_eq!(n, -333333333333i64);
630 ///
631 /// let mut n = Integer::from(-10);
632 /// assert_eq!(n.div_round_assign(Integer::from(5), Exact), Equal);
633 /// assert_eq!(n, -2);
634 ///
635 /// let mut n = Integer::from(-10);
636 /// assert_eq!(n.div_round_assign(Integer::from(3), Nearest), Greater);
637 /// assert_eq!(n, -3);
638 ///
639 /// let mut n = Integer::from(-20);
640 /// assert_eq!(n.div_round_assign(Integer::from(3), Nearest), Less);
641 /// assert_eq!(n, -7);
642 ///
643 /// let mut n = Integer::from(-10);
644 /// assert_eq!(n.div_round_assign(Integer::from(4), Nearest), Greater);
645 /// assert_eq!(n, -2);
646 ///
647 /// let mut n = Integer::from(-14);
648 /// assert_eq!(n.div_round_assign(Integer::from(4), Nearest), Less);
649 /// assert_eq!(n, -4);
650 ///
651 /// let mut n = Integer::from(-10);
652 /// assert_eq!(n.div_round_assign(Integer::from(-4), Down), Less);
653 /// assert_eq!(n, 2);
654 ///
655 /// let mut n = -Integer::from(10u32).pow(12);
656 /// assert_eq!(n.div_round_assign(Integer::from(-3), Floor), Less);
657 /// assert_eq!(n, 333333333333i64);
658 ///
659 /// let mut n = Integer::from(-10);
660 /// assert_eq!(n.div_round_assign(Integer::from(-4), Up), Greater);
661 /// assert_eq!(n, 3);
662 ///
663 /// let mut n = -Integer::from(10u32).pow(12);
664 /// assert_eq!(n.div_round_assign(Integer::from(-3), Ceiling), Greater);
665 /// assert_eq!(n, 333333333334i64);
666 ///
667 /// let mut n = Integer::from(-10);
668 /// assert_eq!(n.div_round_assign(Integer::from(-5), Exact), Equal);
669 /// assert_eq!(n, 2);
670 ///
671 /// let mut n = Integer::from(-10);
672 /// assert_eq!(n.div_round_assign(Integer::from(-3), Nearest), Less);
673 /// assert_eq!(n, 3);
674 ///
675 /// let mut n = Integer::from(-20);
676 /// assert_eq!(n.div_round_assign(Integer::from(-3), Nearest), Greater);
677 /// assert_eq!(n, 7);
678 ///
679 /// let mut n = Integer::from(-10);
680 /// assert_eq!(n.div_round_assign(Integer::from(-4), Nearest), Less);
681 /// assert_eq!(n, 2);
682 ///
683 /// let mut n = Integer::from(-14);
684 /// assert_eq!(n.div_round_assign(Integer::from(-4), Nearest), Greater);
685 /// assert_eq!(n, 4);
686 /// ```
687 fn div_round_assign(&mut self, other: Self, rm: RoundingMode) -> Ordering {
688 let q_sign = self.sign == other.sign;
689 let o = self
690 .abs
691 .div_round_assign(other.abs, if q_sign { rm } else { -rm });
692 self.sign = q_sign || self.abs == 0u32;
693 if q_sign { o } else { o.reverse() }
694 }
695}
696
697impl DivRoundAssign<&Self> for Integer {
698 /// Divides an [`Integer`] by another [`Integer`] in place, taking the [`Integer`] on the
699 /// right-hand side by reference and rounding according to a specified rounding mode. An
700 /// [`Ordering`] is returned, indicating whether the assigned value is less than, equal to, or
701 /// greater than the exact value.
702 ///
703 /// See the [`DivRound`] documentation for details.
704 ///
705 /// # Worst-case complexity
706 /// $T(n) = O(n \log n \log \log n)$
707 ///
708 /// $M(n) = O(n \log n)$
709 ///
710 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
711 ///
712 /// # Panics
713 /// Panics if `other` is zero, or if `rm` is `Exact` but `self` is not divisible by `other`.
714 ///
715 /// # Examples
716 /// ```
717 /// use core::cmp::Ordering::*;
718 /// use malachite_base::num::arithmetic::traits::{DivRoundAssign, Pow};
719 /// use malachite_base::rounding_modes::RoundingMode::*;
720 /// use malachite_nz::integer::Integer;
721 ///
722 /// let mut n = Integer::from(-10);
723 /// assert_eq!(n.div_round_assign(&Integer::from(4), Down), Greater);
724 /// assert_eq!(n, -2);
725 ///
726 /// let mut n = -Integer::from(10u32).pow(12);
727 /// assert_eq!(n.div_round_assign(&Integer::from(3), Floor), Less);
728 /// assert_eq!(n, -333333333334i64);
729 ///
730 /// let mut n = Integer::from(-10);
731 /// assert_eq!(n.div_round_assign(&Integer::from(4), Up), Less);
732 /// assert_eq!(n, -3);
733 ///
734 /// let mut n = -Integer::from(10u32).pow(12);
735 /// assert_eq!(n.div_round_assign(&Integer::from(3), Ceiling), Greater);
736 /// assert_eq!(n, -333333333333i64);
737 ///
738 /// let mut n = Integer::from(-10);
739 /// assert_eq!(n.div_round_assign(&Integer::from(5), Exact), Equal);
740 /// assert_eq!(n, -2);
741 ///
742 /// let mut n = Integer::from(-10);
743 /// assert_eq!(n.div_round_assign(&Integer::from(3), Nearest), Greater);
744 /// assert_eq!(n, -3);
745 ///
746 /// let mut n = Integer::from(-20);
747 /// assert_eq!(n.div_round_assign(&Integer::from(3), Nearest), Less);
748 /// assert_eq!(n, -7);
749 ///
750 /// let mut n = Integer::from(-10);
751 /// assert_eq!(n.div_round_assign(&Integer::from(4), Nearest), Greater);
752 /// assert_eq!(n, -2);
753 ///
754 /// let mut n = Integer::from(-14);
755 /// assert_eq!(n.div_round_assign(&Integer::from(4), Nearest), Less);
756 /// assert_eq!(n, -4);
757 ///
758 /// let mut n = Integer::from(-10);
759 /// assert_eq!(n.div_round_assign(&Integer::from(-4), Down), Less);
760 /// assert_eq!(n, 2);
761 ///
762 /// let mut n = -Integer::from(10u32).pow(12);
763 /// assert_eq!(n.div_round_assign(&Integer::from(-3), Floor), Less);
764 /// assert_eq!(n, 333333333333i64);
765 ///
766 /// let mut n = Integer::from(-10);
767 /// assert_eq!(n.div_round_assign(&Integer::from(-4), Up), Greater);
768 /// assert_eq!(n, 3);
769 ///
770 /// let mut n = -Integer::from(10u32).pow(12);
771 /// assert_eq!(n.div_round_assign(&Integer::from(-3), Ceiling), Greater);
772 /// assert_eq!(n, 333333333334i64);
773 ///
774 /// let mut n = Integer::from(-10);
775 /// assert_eq!(n.div_round_assign(&Integer::from(-5), Exact), Equal);
776 /// assert_eq!(n, 2);
777 ///
778 /// let mut n = Integer::from(-10);
779 /// assert_eq!(n.div_round_assign(&Integer::from(-3), Nearest), Less);
780 /// assert_eq!(n, 3);
781 ///
782 /// let mut n = Integer::from(-20);
783 /// assert_eq!(n.div_round_assign(&Integer::from(-3), Nearest), Greater);
784 /// assert_eq!(n, 7);
785 ///
786 /// let mut n = Integer::from(-10);
787 /// assert_eq!(n.div_round_assign(&Integer::from(-4), Nearest), Less);
788 /// assert_eq!(n, 2);
789 ///
790 /// let mut n = Integer::from(-14);
791 /// assert_eq!(n.div_round_assign(&Integer::from(-4), Nearest), Greater);
792 /// assert_eq!(n, 4);
793 /// ```
794 fn div_round_assign(&mut self, other: &Self, rm: RoundingMode) -> Ordering {
795 let q_sign = self.sign == other.sign;
796 let o = self
797 .abs
798 .div_round_assign(&other.abs, if q_sign { rm } else { -rm });
799 self.sign = q_sign || self.abs == 0u32;
800 if q_sign { o } else { o.reverse() }
801 }
802}