Skip to main content

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);