use std::{ cmp::Ordering, convert::From, fmt, hash::{Hash, Hasher}, ops::{ Add, AddAssign, BitAnd, BitOr, BitXor, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, Shr, Sub, SubAssign, }, str::FromStr, }; #[derive(Debug, Clone, Copy)] pub struct BigInt { bytes: [u8; N], len: usize, } impl BigInt { pub fn from_bytes(bytes: &[u8]) -> Self { debug_assert!(bytes.len() != 0); let mut len = bytes.len(); while len > 1 && bytes[len - 1] == 0 { len -= 1; } let mut arr = [0u8; N]; arr[..len].copy_from_slice(&bytes[..len]); BigInt { bytes: arr, len } } pub fn from_u64(value: u64) -> Self { Self::from_bytes(&value.to_le_bytes()) } fn trim_zeros(mut self) -> Self { while self.len > 1 && self.bytes[self.len - 1] == 0 { self.len -= 1; } self } pub fn max_value() -> Self { let mut arr = [0u8; N]; arr.fill(255); BigInt { bytes: arr, len: N } } pub fn div_rem(&self, other: &Self) -> (Self, Self) { let mut quotient = BigInt::from(0); let mut remainder = self.clone(); let divisor = other.clone(); while remainder >= divisor { let mut multiple = divisor.clone(); let mut temp_quotient = BigInt::from(1); while multiple + multiple <= remainder { multiple = multiple + multiple; temp_quotient = temp_quotient + temp_quotient; } remainder = remainder - multiple; quotient = quotient + temp_quotient; } (quotient.trim_zeros(), remainder.trim_zeros()) } } impl Add for BigInt { type Output = Self; fn add(self, rhs: Self) -> Self { let mut result = [0u8; N]; let mut carry = 0u16; let max_len = self.len.max(rhs.len); let mut res_len = 0; for i in 0..max_len { let a = self.bytes.get(i).copied().unwrap_or(0) as u16; let b = rhs.bytes.get(i).copied().unwrap_or(0) as u16; let sum = a + b + carry; result[i] = (sum % 256) as u8; carry = sum / 256; res_len = i + 1; } if carry > 0 { result[res_len] = carry as u8; res_len += 1; } BigInt { bytes: result, len: res_len, } .trim_zeros() } } impl AddAssign for BigInt { fn add_assign(&mut self, rhs: Self) { *self = *self + rhs; } } impl Sub for BigInt { type Output = Self; fn sub(self, rhs: Self) -> Self { let mut result = [0u8; N]; let mut borrow = 0i16; let mut res_len = 0; for i in 0..self.len { let a = self.bytes[i] as i16; let b = rhs.bytes.get(i).copied().unwrap_or(0) as i16; let mut diff = a - b - borrow; borrow = 0; if diff < 0 { diff += 256; borrow = 1; } result[i] = diff as u8; res_len = i + 1; } BigInt { bytes: result, len: res_len, } .trim_zeros() } } impl SubAssign for BigInt { fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs; } } impl Mul for BigInt { type Output = Self; fn mul(self, rhs: Self) -> Self { let mut result = BigInt { bytes: [0; N], len: 0, }; for i in 0..self.len { let mut carry = 0u16; for j in 0..rhs.len { let idx = i + j; if idx >= N { panic!("Multiplication overflow"); } let product = self.bytes[i] as u16 * rhs.bytes[j] as u16 + carry + result.bytes[idx] as u16; result.bytes[idx] = (product % 256) as u8; carry = product / 256; } let mut k = i + rhs.len; while carry > 0 && k < N { let sum = result.bytes[k] as u16 + carry; result.bytes[k] = (sum % 256) as u8; carry = sum / 256; k += 1; } result.len = result.len.max(k); } result.trim_zeros() } } impl MulAssign for BigInt { fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; } } impl Div for BigInt { type Output = Self; fn div(self, rhs: Self) -> Self { self.div_rem(&rhs).0 } } impl DivAssign for BigInt { fn div_assign(&mut self, rhs: Self) { *self = *self / rhs; } } impl Rem for BigInt { type Output = Self; fn rem(self, rhs: Self) -> Self { self.div_rem(&rhs).1 } } impl RemAssign for BigInt { fn rem_assign(&mut self, rhs: Self) { *self = *self % rhs; } } impl PartialEq for BigInt { fn eq(&self, other: &Self) -> bool { self.bytes[..self.len] == other.bytes[..other.len] } } impl Eq for BigInt {} impl Hash for BigInt { fn hash(&self, state: &mut H) { self.bytes[..self.len].hash(state); } } impl PartialOrd for BigInt { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for BigInt { fn cmp(&self, other: &Self) -> Ordering { if self.len != other.len { return self.len.cmp(&other.len); } for i in (0..self.len).rev() { match self.bytes[i].cmp(&other.bytes[i]) { Ordering::Equal => continue, ord => return ord, } } Ordering::Equal } } impl Deref for BigInt { type Target = [u8]; fn deref(&self) -> &[u8] { &self.bytes[..self.len] } } impl DerefMut for BigInt { fn deref_mut(&mut self) -> &mut [u8] { &mut self.bytes[..self.len] } } macro_rules! impl_from_int { ($($t:ty),*) => {$( impl From<$t> for BigInt { fn from(value: $t) -> Self { let bytes = value.to_le_bytes(); Self::from_bytes(&bytes) } } )*}; } impl_from_int!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128); impl FromStr for BigInt { type Err = &'static str; fn from_str(s: &str) -> Result { let mut result = BigInt::from(0u8); for c in s.chars() { if !c.is_digit(10) { return Err("Invalid digit"); } let digit = c.to_digit(10).unwrap() as u8; result = result * BigInt::from(10u8) + BigInt::from(digit); } Ok(result) } } impl fmt::Display for BigInt { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.len == 0 { return write!(f, "0"); } let mut digits = Vec::new(); let mut bytes = self.bytes[..self.len].to_vec(); while !bytes.is_empty() { let mut remainder = 0u16; for byte in bytes.iter_mut().rev() { let value = *byte as u16 + remainder * 256; *byte = (value / 10) as u8; remainder = value % 10; } digits.push(remainder as u8); while !bytes.is_empty() && bytes[bytes.len() - 1] == 0 { bytes.pop(); } } digits.reverse(); let s = digits .iter() .map(|d| char::from_digit(*d as u32, 10).unwrap()) .collect::(); write!(f, "{}", s) } } #[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] struct Dint { bytes: Vec, } impl Deref for Dint { type Target = [u8]; fn deref(&self) -> &[u8] { &self.bytes } } impl DerefMut for Dint { fn deref_mut(&mut self) -> &mut [u8] { &mut self.bytes } } pub fn main() { type TheInt = BigInt<2>; let mut test: TheInt = TheInt::max_value(); let thing = BigInt::<9>::max_value(); test /= 2.into(); println!("{test}") }