numera/number/integer/pz/
integer.rs1use crate::number::{
7 integer::{pz::*, Integer},
8 traits::ConstOne,
9};
10use devela::convert::az::CheckedAs;
11
12#[cfg(not(feature = "std"))]
13use crate::all::is_prime;
14#[cfg(feature = "std")]
15use crate::all::is_prime_sieve;
16
17macro_rules! impl_nonzero_integer {
18 (many: $($t:ident, $inner:ident),+) => {
21 $( impl_nonzero_integer![$t, $inner]; )+
22 };
23 ($t:ident, $inner:ident) => {
24 impl $t {
26 #[inline]
28 #[must_use]
29 pub const fn is_even(&self) -> bool {
30 self.0.get() & 1 == 0
31 }
32 #[inline]
34 #[must_use]
35 pub const fn is_odd(&self) -> bool {
36 !self.is_even()
37 }
38
39 #[inline]
41 #[must_use]
42 pub const fn is_multiple_of(&self, other: &Self) -> bool {
43 self.0.get() % other.0.get() == 0
44 }
45 #[inline]
47 #[must_use]
48 pub const fn is_divisor_of(&self, other: &Self) -> bool {
49 other.is_multiple_of(self)
50 }
51
52 #[inline]
58 #[must_use]
59 pub const fn is_coprime(&self, other: &Self) -> bool {
60 self.gcd(other).0.get() == Self::ONE.0.get()
61 }
62
63 #[inline]
65 #[must_use]
66 pub const fn digits(&self) -> usize {
67 self.0.ilog10() as usize + 1
68 }
69 }
70
71 impl $t {
73 #[inline]
79 pub fn is_prime(&self) -> Option<bool> {
80 #[cfg(feature = "std")]
81 return Some(is_prime_sieve((self.0.get()).checked_as::<usize>()?));
82 #[cfg(not(feature = "std"))]
83 return Some(is_prime((self.0.get()).checked_as::<u32>()?));
84 }
85
86 #[inline]
88 #[must_use]
89 pub const fn gcd(&self, other: &Self) -> Self {
90 let (mut a, mut b) = (self.0.get(), other.0.get());
91 while b != 0 {
92 let temp = b;
93 b = a % b;
94 a = temp;
95 }
96 #[cfg(feature = "safe")]
97 if let Ok(n0z) = $t::new(a) {
98 n0z
99 } else {
100 unreachable![]
101 }
102
103 #[cfg(not(feature = "safe"))]
104 return unsafe { $t::new_unchecked(a) };
106 }
107
108 #[inline]
110 #[must_use]
111 pub const fn lcm(&self, other: &Self) -> Self {
112 let lcm = self.0.get() * other.0.get() / self.gcd(other).0.get();
113
114 #[cfg(feature = "safe")]
115 if let Ok(n0z) = $t::new(lcm) {
116 n0z
117 } else {
118 unreachable![]
119 }
120 #[cfg(not(feature = "safe"))]
121 return unsafe { $t::new_unchecked(lcm) };
123 }
124 }
125 impl Integer for $t {
126 #[inline]
127 fn integer_is_even(&self) -> bool {
128 self.is_even()
129 }
130 #[inline]
131 fn integer_is_multiple_of(&self, other: &Self) -> bool {
132 self.is_multiple_of(other)
133 }
134 #[inline]
135 fn integer_is_prime(&self) -> Option<bool> {
136 self.is_prime()
137 }
138 #[inline]
139 fn integer_gcd(&self, other: &Self) -> Option<Self> {
140 Some(self.gcd(other))
141 }
142 #[inline]
143 fn integer_lcm(&self, other: &Self) -> Option<Self> {
144 Some(self.lcm(other))
145 }
146 #[inline]
147 fn integer_digits(&self) -> usize {
148 self.digits()
149 }
150 }
151 };
152}
153
154impl_nonzero_integer![
155 many: PositiveInteger8,
156 NonZeroU8,
157 PositiveInteger16,
158 NonZeroU16,
159 PositiveInteger32,
160 NonZeroU32,
161 PositiveInteger64,
162 NonZeroU64,
163 PositiveInteger128,
164 NonZeroU128
165];
166
167#[cfg(test)]
168mod tests {
169 use crate::error::NumeraResult;
170 use crate::number::integer::pz::*;
171
172 #[test]
173 fn pz_lcm_gcd() -> NumeraResult<()> {
174 let pz10 = Pz32::new(10)?;
175 let pz15 = Pz32::new(15)?;
176
177 assert_eq![Pz32::new(30)?, pz10.lcm(&pz15)];
178 assert_eq![Pz32::new(5)?, pz10.gcd(&pz15)];
179 Ok(())
180 }
181}