use crate::UBigInt;
impl UBigInt {
#[must_use = "method returns a new number and does not mutate the original value"]
pub fn rem_ubi(&self, other: &UBigInt) -> Self {
let sdo = self.div_ubi(other).mul_ubi(other);
#[cfg(test)] assert!(self.geq_ubi(&sdo));
self.sub_ubi(&sdo)
}
pub fn rem_ubi_mut(&mut self, other: &UBigInt) {
let sdo = self.div_ubi(other).mul_ubi(other);
#[cfg(test)] assert!(self.geq_ubi(&sdo));
self.sub_ubi_mut(&sdo);
}
#[must_use = "method returns a new number and does not mutate the original value"]
pub fn rem_u32(&self, other: u32) -> Self {
let other = other as u64;
let unit = (1 << 32) % other;
let mut curr_power = 1;
let mut result: u64 = 0;
for d in self.0.iter() {
result += (*d as u64 % other) * curr_power % other;
curr_power *= unit;
curr_power %= other;
}
let result = UBigInt::from_u32((result % other) as u32);
#[cfg(test)] {
let t = self.rem_ubi(&UBigInt::from_u32(other as u32));
assert_eq!(t, result);
assert!(result.is_valid());
}
result
}
pub fn rem_u32_mut(&mut self, other: u32) {
let unit = ((1 << 32) % other as u64) as u32;
let mut curr_power = 1;
let mut result = 0;
for d in self.0.iter() {
result += (d % other) * curr_power % other;
curr_power *= unit;
curr_power %= other;
}
*self = UBigInt::from_u32(result % other);
#[cfg(test)] {
let mut t = self.rem_ubi(&UBigInt::from_u32(other as u32));
assert_eq!(&mut t, self);
assert!(self.is_valid());
}
}
#[must_use = "method returns a new number and does not mutate the original value"]
pub fn rem_pow2(&self, other: u32) -> Self {
let result = UBigInt::from_u32(self.0[0] % other);
#[cfg(test)] {
assert!(is_pow2(other));
assert_eq!(result, self.rem_u32(other));
}
result
}
}
#[cfg(test)]
fn is_pow2(mut n: u32) -> bool {
while n > 4 {
if n % 2 == 1 {
return false;
}
n /= 2;
}
n == 1 || n == 2 || n == 4
}