malachite_base/num/arithmetic/div_mod_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::num::arithmetic::traits::{DivAssignModEuclidean, DivModEuclidean};
10
11macro_rules! impl_div_mod_euclidean {
12 ($t:ident) => {
13 impl DivModEuclidean<$t> for $t {
14 type DivOutput = $t;
15 type ModOutput = $t;
16
17 /// Divides a number by another number, returning the quotient and remainder. The
18 /// quotient is rounded so that the remainder is nonnegative.
19 ///
20 /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < |y|$.
21 ///
22 /// $$
23 /// f(x, y) = \left ( \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor,
24 /// \space x-y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor \right).
25 /// $$
26 ///
27 /// For unsigned integers, `div_mod_euclidean` is equivalent to
28 /// [`div_mod`](super::traits::DivMod::div_mod).
29 ///
30 /// # Worst-case complexity
31 /// Constant time and additional memory.
32 ///
33 /// # Panics
34 /// Panics if `other` is 0, or if `self` is `$t::MIN` and `other` is -1 (when `$t` is
35 /// signed).
36 ///
37 /// # Examples
38 /// See [here](super::div_mod_euclidean#div_mod_euclidean).
39 #[inline]
40 fn div_mod_euclidean(self, other: $t) -> ($t, $t) {
41 (self.div_euclid(other), self.rem_euclid(other))
42 }
43 }
44
45 impl DivAssignModEuclidean<$t> for $t {
46 type ModOutput = $t;
47
48 /// Divides a number by another number in place, returning the remainder. The quotient
49 /// is rounded so that the remainder is nonnegative.
50 ///
51 /// The quotient and remainder satisfy $x = qy + r$ and $0 \leq r < |y|$.
52 ///
53 /// $$
54 /// f(x, y) = x - y \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor,
55 /// $$
56 /// $$
57 /// x \gets \operatorname{sgn}(y) \left \lfloor \frac{x}{|y|} \right \rfloor.
58 /// $$
59 ///
60 /// For unsigned integers, `div_assign_mod_euclidean` is equivalent to
61 /// [`div_assign_mod`](super::traits::DivAssignMod::div_assign_mod).
62 ///
63 /// # Worst-case complexity
64 /// Constant time and additional memory.
65 ///
66 /// # Panics
67 /// Panics if `other` is 0, or if `self` is `$t::MIN` and `other` is -1 (when `$t` is
68 /// signed).
69 ///
70 /// # Examples
71 /// See [here](super::div_mod_euclidean#div_assign_mod_euclidean).
72 #[inline]
73 fn div_assign_mod_euclidean(&mut self, other: $t) -> $t {
74 let q = self.div_euclid(other);
75 let r = self.rem_euclid(other);
76 *self = q;
77 r
78 }
79 }
80 };
81}
82apply_to_primitive_ints!(impl_div_mod_euclidean);