fixed_bigint/fixeduint/
num_integer_impl.rs

1use super::{FixedUInt, MachineWord};
2
3use num_traits::{One, PrimInt, Zero};
4
5// Most code here from num_integer crate, unsigned implementation
6
7impl<T: MachineWord, const N: usize> num_integer::Integer for FixedUInt<T, N> {
8    fn div_floor(&self, other: &Self) -> Self {
9        *self / *other
10    }
11    fn mod_floor(&self, other: &Self) -> Self {
12        *self % *other
13    }
14    fn gcd(&self, other: &Self) -> Self {
15        // Use Stein's algorithm
16        let mut m = *self;
17        let mut n = *other;
18        let zero = Self::zero();
19        if m == zero || n == zero {
20            return m | n;
21        }
22
23        // find common factors of 2
24        let shift = (m | n).trailing_zeros();
25
26        // divide n and m by 2 until odd
27        m = m >> m.trailing_zeros();
28        n = n >> n.trailing_zeros();
29
30        while m != n {
31            if m > n {
32                m -= n;
33                m = m >> m.trailing_zeros();
34            } else {
35                n -= m;
36                n = n >> n.trailing_zeros();
37            }
38        }
39        m << shift
40    }
41    fn lcm(&self, other: &Self) -> Self {
42        if self.is_zero() && other.is_zero() {
43            return Self::zero();
44        }
45        let gcd = self.gcd(other);
46        *self * (*other / gcd)
47    }
48    fn divides(&self, other: &Self) -> bool {
49        self.is_multiple_of(other)
50    }
51    fn is_multiple_of(&self, other: &Self) -> bool {
52        (*self) % other == Self::zero()
53    }
54    fn is_even(&self) -> bool {
55        (*self) & Self::one() == Self::zero()
56    }
57    fn is_odd(&self) -> bool {
58        !self.is_even()
59    }
60    fn div_rem(&self, other: &Self) -> (Self, Self) {
61        self.div_rem(other)
62    }
63}