diff --git a/src/number/mul.rs b/src/number/mul.rs index 45661db..65c8121 100644 --- a/src/number/mul.rs +++ b/src/number/mul.rs @@ -7,42 +7,43 @@ impl Mul for Number { #[allow(clippy::suspicious_arithmetic_impl)] fn mul(self, rhs: Self) -> Self::Output { - println!("left {self:#?}"); - println!("right {rhs:#?}"); - let mut mult_vecs = Vec::new(); let sign = match (self.sign, rhs.sign) { (Sign::Positif, Sign::Positif) => Sign::Positif, (Sign::Positif, Sign::Negatif) => Sign::Negatif, (Sign::Negatif, Sign::Positif) => Sign::Negatif, (Sign::Negatif, Sign::Negatif) => Sign::Positif, }; - for (idx, rdigit) in rhs.digits.iter().enumerate() { - let rdigit = rdigit * 10_isize.pow(idx as u32); - let mult_vec: Vec = self.digits.iter().map(|ldigit| ldigit * rdigit).collect(); - let mut normalized_mult_vec = Vec::new(); - let mut carry = 0; - let mut add_zero = true; - mult_vec.into_iter().for_each(|digit| { - let digit = digit + carry; - if digit > 9 { - carry = digit % 10; - normalized_mult_vec.insert(0, digit / 10); + let mut digits = Vec::new(); + for (zeroes, rdigit) in rhs.digits.iter().enumerate() { + for (idx, ldigit) in self.digits.iter().enumerate() { + let mult = rdigit * ldigit; + let new = mult % 10; + let mut carry = mult / 10; + if let Some(old) = digits.get(zeroes + idx) { + let add = old + new; + digits[zeroes + idx] = add % 10; + carry += add / 10; } else { - normalized_mult_vec.insert(0, digit); - carry = 0; - add_zero = false; + digits.push(new); + } + let mut carry_idx = 1; + loop { + if carry == 0 { + break; + } + if let Some(old) = digits.get(zeroes + idx + carry_idx) { + let add = old + carry; + digits[zeroes + idx + carry_idx] = add % 10; + carry = add / 10; + } else { + digits.push(carry % 10); + carry /= 10; + } + carry_idx += 1; } - }); - if carry != 0 || add_zero { - normalized_mult_vec.insert(0, carry); } - mult_vecs.push(Number { - digits: normalized_mult_vec, - sign, - }); } - - mult_vecs.into_iter().reduce(|acc, num| acc + num).unwrap() + Number { digits, sign } } } @@ -123,7 +124,15 @@ mod test_number_mul { } #[test] - fn mul_big() { + fn mul_big_1() { + let a = Number::from("123"); + let b = Number::from("321"); + let res = Number::from("39483"); + assert_eq!(res, a * b); + } + + #[test] + fn mul_big_2() { let a = Number::from("123456789"); let b = Number::from("987654321"); let res = Number::from("121932631112635269");