hmath/bigint/arith/
rem.rs

1use crate::BigInt;
2
3impl BigInt {
4
5    // self - self / other * other
6    #[must_use = "method returns a new number and does not mutate the original value"]
7    pub fn rem_bi(&self, other: &BigInt) -> Self {
8        let mut sdo = self.div_bi(other);
9        sdo.mul_bi_mut(other);
10
11        let result = self.sub_bi(&sdo);
12
13        #[cfg(test)] assert!(result.is_valid());
14
15        result
16    }
17
18    pub fn rem_bi_mut(&mut self, other: &BigInt) {
19        let mut sdo = self.div_bi(other);
20        sdo.mul_bi_mut(other);
21        self.sub_bi_mut(&sdo);
22        #[cfg(test)] assert!(self.is_valid());
23    }
24
25    // x % y = x % -y
26    // x % y = -(-x % y)
27    #[must_use = "method returns a new number and does not mutate the original value"]
28    pub fn rem_i32(&self, other: i32) -> Self {
29        let new_val = self.val.rem_u32(other.abs() as u32);
30        let is_neg = self.is_neg() & !new_val.is_zero();
31
32        let result = BigInt::from_ubi(new_val, is_neg);
33
34        #[cfg(test)] assert!(result.is_valid());
35
36        result
37    }
38
39    pub fn rem_i32_mut(&mut self, other: i32) {
40        self.val.rem_u32_mut(other.abs() as u32);
41        self._is_neg = self.is_neg() & !self.val.is_zero();
42        #[cfg(test)] assert!(self.is_valid());
43    }
44
45    /// `other` must be a power of 2
46    #[must_use = "method returns a new number and does not mutate the original value"]
47    pub fn rem_pow2(&self, other: i32) -> Self {
48        let new_val = self.val.rem_pow2(other.abs() as u32);
49        let is_neg = self.is_neg() & !new_val.is_zero();
50
51        BigInt::from_ubi(new_val, is_neg)
52    }
53
54}
55
56#[cfg(test)]
57mod tests {
58    use crate::BigInt;
59
60    #[test]
61    fn sign_test() {
62
63        for x in -7..8 {
64
65            for y in -7..8 {
66
67                if y == 0 {
68                    continue;
69                }
70
71                let mut x1 = BigInt::from_i32(x);
72                let y1 = BigInt::from_i32(y);
73                let mut x2 = BigInt::from_i32(x);
74                let res1 = x1.rem_bi(&y1);
75                let res2 = x1.rem_i32(y);
76                let res3 = BigInt::from_i32(x % y);
77                x1.rem_bi_mut(&y1);
78                x2.rem_i32_mut(y);
79
80                assert_eq!(x1, x2);
81                assert_eq!(res1, res2);
82                assert_eq!(res2, res3);
83                assert_eq!(res1, x1);
84                assert_eq!(res2, x2);
85            }
86
87        }
88
89    }
90
91}