dashu_base/ring/
div_rem.rs1use super::{DivEuclid, DivRem, DivRemAssign, DivRemEuclid, RemEuclid};
2
3macro_rules! impl_div_rem_ops_prim {
4 ($($T:ty)*) => {$(
5 impl DivRem for $T {
6 type OutputDiv = $T;
7 type OutputRem = $T;
8 #[inline]
9 fn div_rem(self, rhs: $T) -> ($T, $T) {
10 (self / rhs, self % rhs)
11 }
12 }
13 impl DivRemAssign for $T {
14 type OutputRem = $T;
15 #[inline]
16 fn div_rem_assign(&mut self, rhs: $T) -> $T {
17 let r = *self % rhs;
18 *self /= rhs;
19 r
20 }
21 }
22 impl DivEuclid for $T {
23 type Output = $T;
24 #[inline]
25 fn div_euclid(self, rhs: $T) -> $T {
26 <$T>::div_euclid(self, rhs)
27 }
28 }
29 impl RemEuclid for $T {
30 type Output = $T;
31 #[inline]
32 fn rem_euclid(self, rhs: $T) -> $T {
33 <$T>::rem_euclid(self, rhs)
34 }
35 }
36 impl DivRemEuclid for $T {
37 type OutputDiv = $T;
38 type OutputRem = $T;
39 #[inline]
40 fn div_rem_euclid(self, rhs: $T) -> ($T, $T) {
41 let (q, r) = (self / rhs, self % rhs);
42
43 #[allow(unused_comparisons)]
45 if r >= 0 {
46 (q, r)
47 } else if rhs >= 0{
48 (q - 1, r + rhs)
49 } else {
50 (q + 1, r - rhs)
51 }
52 }
53 }
54 )*}
55}
56impl_div_rem_ops_prim!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn test_simple() {
64 assert_eq!(7u32.div_rem(4), (1, 3));
65 assert_eq!(7u32.div_rem_euclid(4), (1, 3));
66 assert_eq!(7i32.div_rem(-4), (-1, 3));
67 assert_eq!(7i32.div_rem_euclid(-4), (-1, 3));
68 assert_eq!((-7i32).div_rem(4), (-1, -3));
69 assert_eq!((-7i32).div_rem_euclid(4), (-2, 1));
70 assert_eq!((-7i32).div_rem(-4), (1, -3));
71 assert_eq!((-7i32).div_rem_euclid(-4), (2, 1));
72
73 let mut n = 7u32;
74 let r = n.div_rem_assign(4);
75 assert!(n == 1 && r == 3);
76 }
77}