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