dashu_int/third_party/
num_integer.rs1use crate::{ibig::IBig, ubig::UBig};
4use dashu_base::{BitTest, CubicRoot, DivRem, ExtendedGcd, Gcd, Sign, SquareRoot};
5use num_integer_v01 as num_integer;
6
7impl num_integer::Integer for UBig {
8 #[inline]
9 fn div_floor(&self, other: &Self) -> Self {
10 self / other
11 }
12 #[inline]
13 fn div_rem(&self, other: &Self) -> (Self, Self) {
14 DivRem::div_rem(self, other)
15 }
16 #[inline]
17 fn mod_floor(&self, other: &Self) -> Self {
18 self & other
19 }
20 #[inline]
21 fn divides(&self, other: &Self) -> bool {
22 (self % other).is_zero()
23 }
24 #[inline]
25 fn is_multiple_of(&self, other: &Self) -> bool {
26 UBig::is_multiple_of(self, other)
27 }
28 #[inline]
29 fn is_even(&self) -> bool {
30 !self.bit(0)
31 }
32 #[inline]
33 fn is_odd(&self) -> bool {
34 self.bit(0)
35 }
36 #[inline]
37 fn gcd(&self, other: &Self) -> Self {
38 Gcd::gcd(self, other)
39 }
40 #[inline]
41 fn lcm(&self, other: &Self) -> Self {
42 if self.is_zero() && other.is_zero() {
43 UBig::ZERO
44 } else {
45 self / Gcd::gcd(self, other) * other
46 }
47 }
48 #[inline]
49 fn extended_gcd(&self, other: &Self) -> num_integer::ExtendedGcd<Self> {
50 let (g, x, y) = ExtendedGcd::gcd_ext(self, other);
51 num_integer::ExtendedGcd {
52 gcd: g,
53 x: x.try_into().unwrap(),
54 y: y.try_into().unwrap(),
55 }
56 }
57}
58
59impl num_integer::Roots for UBig {
60 #[inline]
61 fn sqrt(&self) -> Self {
62 SquareRoot::sqrt(self)
63 }
64 #[inline]
65 fn cbrt(&self) -> Self {
66 CubicRoot::cbrt(self)
67 }
68 #[inline]
69 fn nth_root(&self, n: u32) -> Self {
70 self.nth_root(n as usize)
71 }
72}
73
74impl num_integer::Integer for IBig {
75 #[inline]
76 fn div_floor(&self, other: &Self) -> Self {
77 let (q, r) = DivRem::div_rem(self, other);
78 if !r.is_zero() && q.sign() == Sign::Negative {
79 q - IBig::ONE
80 } else {
81 q
82 }
83 }
84 #[inline]
85 fn div_rem(&self, other: &Self) -> (Self, Self) {
86 DivRem::div_rem(self, other)
87 }
88 #[inline]
89 fn mod_floor(&self, other: &Self) -> Self {
90 let r = self % other;
91 if !r.is_zero() && self.sign() * other.sign() == Sign::Negative {
92 other + r
93 } else {
94 r
95 }
96 }
97 #[inline]
98 fn divides(&self, other: &Self) -> bool {
99 (self % other).is_zero()
100 }
101 #[inline]
102 fn is_multiple_of(&self, other: &Self) -> bool {
103 IBig::is_multiple_of(self, other)
104 }
105 #[inline]
106 fn is_even(&self) -> bool {
107 (self & IBig::ONE).is_zero()
108 }
109 #[inline]
110 fn is_odd(&self) -> bool {
111 (self & IBig::ONE).is_one()
112 }
113 #[inline]
114 fn gcd(&self, other: &Self) -> Self {
115 Gcd::gcd(self, other).into()
116 }
117 #[inline]
118 fn lcm(&self, other: &Self) -> Self {
119 if self.is_zero() && other.is_zero() {
120 IBig::ZERO
121 } else {
122 self / Gcd::gcd(self, other) * other
123 }
124 }
125 #[inline]
126 fn extended_gcd(&self, other: &Self) -> num_integer::ExtendedGcd<Self> {
127 let (g, x, y) = ExtendedGcd::gcd_ext(self, other);
128 num_integer::ExtendedGcd {
129 gcd: g.into(),
130 x,
131 y,
132 }
133 }
134}
135
136impl num_integer::Roots for IBig {
137 #[inline]
138 fn sqrt(&self) -> Self {
139 SquareRoot::sqrt(self).into()
140 }
141 #[inline]
142 fn cbrt(&self) -> Self {
143 CubicRoot::cbrt(self)
144 }
145 #[inline]
146 fn nth_root(&self, n: u32) -> Self {
147 self.nth_root(n as usize)
148 }
149}