1fad3a1d3Sopenharmony_ciuse std::ops::{AddAssign, MulAssign}; 2fad3a1d3Sopenharmony_ci 3fad3a1d3Sopenharmony_ci// For implementing base10_digits() accessor on LitInt. 4fad3a1d3Sopenharmony_cipub(crate) struct BigInt { 5fad3a1d3Sopenharmony_ci digits: Vec<u8>, 6fad3a1d3Sopenharmony_ci} 7fad3a1d3Sopenharmony_ci 8fad3a1d3Sopenharmony_ciimpl BigInt { 9fad3a1d3Sopenharmony_ci pub(crate) fn new() -> Self { 10fad3a1d3Sopenharmony_ci BigInt { digits: Vec::new() } 11fad3a1d3Sopenharmony_ci } 12fad3a1d3Sopenharmony_ci 13fad3a1d3Sopenharmony_ci pub(crate) fn to_string(&self) -> String { 14fad3a1d3Sopenharmony_ci let mut repr = String::with_capacity(self.digits.len()); 15fad3a1d3Sopenharmony_ci 16fad3a1d3Sopenharmony_ci let mut has_nonzero = false; 17fad3a1d3Sopenharmony_ci for digit in self.digits.iter().rev() { 18fad3a1d3Sopenharmony_ci has_nonzero |= *digit != 0; 19fad3a1d3Sopenharmony_ci if has_nonzero { 20fad3a1d3Sopenharmony_ci repr.push((*digit + b'0') as char); 21fad3a1d3Sopenharmony_ci } 22fad3a1d3Sopenharmony_ci } 23fad3a1d3Sopenharmony_ci 24fad3a1d3Sopenharmony_ci if repr.is_empty() { 25fad3a1d3Sopenharmony_ci repr.push('0'); 26fad3a1d3Sopenharmony_ci } 27fad3a1d3Sopenharmony_ci 28fad3a1d3Sopenharmony_ci repr 29fad3a1d3Sopenharmony_ci } 30fad3a1d3Sopenharmony_ci 31fad3a1d3Sopenharmony_ci fn reserve_two_digits(&mut self) { 32fad3a1d3Sopenharmony_ci let len = self.digits.len(); 33fad3a1d3Sopenharmony_ci let desired = 34fad3a1d3Sopenharmony_ci len + !self.digits.ends_with(&[0, 0]) as usize + !self.digits.ends_with(&[0]) as usize; 35fad3a1d3Sopenharmony_ci self.digits.resize(desired, 0); 36fad3a1d3Sopenharmony_ci } 37fad3a1d3Sopenharmony_ci} 38fad3a1d3Sopenharmony_ci 39fad3a1d3Sopenharmony_ciimpl AddAssign<u8> for BigInt { 40fad3a1d3Sopenharmony_ci // Assumes increment <16. 41fad3a1d3Sopenharmony_ci fn add_assign(&mut self, mut increment: u8) { 42fad3a1d3Sopenharmony_ci self.reserve_two_digits(); 43fad3a1d3Sopenharmony_ci 44fad3a1d3Sopenharmony_ci let mut i = 0; 45fad3a1d3Sopenharmony_ci while increment > 0 { 46fad3a1d3Sopenharmony_ci let sum = self.digits[i] + increment; 47fad3a1d3Sopenharmony_ci self.digits[i] = sum % 10; 48fad3a1d3Sopenharmony_ci increment = sum / 10; 49fad3a1d3Sopenharmony_ci i += 1; 50fad3a1d3Sopenharmony_ci } 51fad3a1d3Sopenharmony_ci } 52fad3a1d3Sopenharmony_ci} 53fad3a1d3Sopenharmony_ci 54fad3a1d3Sopenharmony_ciimpl MulAssign<u8> for BigInt { 55fad3a1d3Sopenharmony_ci // Assumes base <=16. 56fad3a1d3Sopenharmony_ci fn mul_assign(&mut self, base: u8) { 57fad3a1d3Sopenharmony_ci self.reserve_two_digits(); 58fad3a1d3Sopenharmony_ci 59fad3a1d3Sopenharmony_ci let mut carry = 0; 60fad3a1d3Sopenharmony_ci for digit in &mut self.digits { 61fad3a1d3Sopenharmony_ci let prod = *digit * base + carry; 62fad3a1d3Sopenharmony_ci *digit = prod % 10; 63fad3a1d3Sopenharmony_ci carry = prod / 10; 64fad3a1d3Sopenharmony_ci } 65fad3a1d3Sopenharmony_ci } 66fad3a1d3Sopenharmony_ci} 67