use std::ops::{Mul, MulAssign}; use super::{Number, Sign}; impl Mul for Number { type Output = Self; #[allow(clippy::suspicious_arithmetic_impl)] fn mul(self, rhs: Self) -> Self::Output { 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, }; 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 { 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; } } } Number { digits, sign } } } impl Mul<Number> for isize { type Output = Number; fn mul(self, rhs: Number) -> Self::Output { Number::from(self) * rhs } } impl Mul<isize> for Number { type Output = Self; fn mul(self, rhs: isize) -> Self::Output { self * Number::from(rhs) } } impl MulAssign for Number { fn mul_assign(&mut self, rhs: Self) { let new = self.clone() * rhs; self.digits = new.digits; self.sign = new.sign; } } #[cfg(test)] mod test_number_mul { use crate::number::Number; #[test] fn mul_positif() { let a = Number::from(9); let b = Number::from(9); let res = Number::from(81); assert_eq!(res, a * b); } #[test] fn mul_negatif() { let a = Number::from(-9); let b = Number::from(-9); let res = Number::from(81); assert_eq!(res, a * b); } #[test] fn mul_positif_with_negatif() { let a = Number::from(9); let b = Number::from(-9); let res = Number::from(-81); assert_eq!(res, a * b); } #[test] fn mul_negatif_with_positif() { let a = Number::from(-9); let b = Number::from(9); let res = Number::from(-81); assert_eq!(res, a * b); } #[test] fn mul_eleven_x_ten() { let a = Number::from(11); let b = Number::from(10); let res = Number::from(110); assert_eq!(res, a * b); } #[test] fn mul_eleven_x_eleven() { let a = Number::from(11); let b = Number::from(11); let res = Number::from(121); assert_eq!(res, a * b); } #[test] 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"); assert_eq!(res, a * b); } }