2024-11-25 10:39:52 +01:00
|
|
|
use std::ops::{Mul, MulAssign};
|
|
|
|
|
|
|
|
use super::{Number, Sign};
|
|
|
|
|
|
|
|
impl Mul for Number {
|
|
|
|
type Output = Self;
|
|
|
|
|
2024-11-26 09:56:20 +01:00
|
|
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
2024-11-25 10:39:52 +01:00
|
|
|
fn mul(self, rhs: Self) -> Self::Output {
|
2024-11-26 09:56:20 +01:00
|
|
|
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<isize> = 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);
|
|
|
|
} else {
|
|
|
|
normalized_mult_vec.insert(0, digit);
|
|
|
|
carry = 0;
|
|
|
|
add_zero = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
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()
|
2024-11-25 10:39:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Mul<Number> for isize {
|
|
|
|
type Output = Number;
|
|
|
|
|
|
|
|
fn mul(self, rhs: Number) -> Self::Output {
|
2024-11-26 09:56:20 +01:00
|
|
|
Number::from(self) * rhs
|
2024-11-25 10:39:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Mul<isize> for Number {
|
|
|
|
type Output = Self;
|
|
|
|
|
|
|
|
fn mul(self, rhs: isize) -> Self::Output {
|
2024-11-26 09:56:20 +01:00
|
|
|
self * Number::from(rhs)
|
2024-11-25 10:39:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MulAssign for Number {
|
|
|
|
fn mul_assign(&mut self, rhs: Self) {
|
|
|
|
let new = self.clone() * rhs;
|
|
|
|
self.digits = new.digits;
|
|
|
|
self.sign = new.sign;
|
|
|
|
}
|
|
|
|
}
|
2024-11-26 09:56:20 +01:00
|
|
|
|
|
|
|
#[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() {
|
|
|
|
let a = Number::from("123456789");
|
|
|
|
let b = Number::from("987654321");
|
|
|
|
let res = Number::from("121932631112635269");
|
|
|
|
assert_eq!(res, a * b);
|
|
|
|
}
|
|
|
|
}
|