Fixed div now all arithmetic operations should work
This commit is contained in:
parent
1e0f6fd077
commit
1bc82a7073
@ -7,30 +7,54 @@ use std::{
|
||||
use super::{Number, Sign};
|
||||
|
||||
impl Number {
|
||||
pub fn div_with_rem(n1: Number, n2: Number) -> Result<(Number, Number), Box<dyn Error>> {
|
||||
if n2 == 0.into() {
|
||||
pub fn div_with_rem(
|
||||
dividend: Number,
|
||||
divisor: Number,
|
||||
) -> Result<(Number, Number), Box<dyn Error>> {
|
||||
if divisor == 0.into() {
|
||||
return Err(Box::from("Division by 0"));
|
||||
}
|
||||
let n1_len = n1.digits.len();
|
||||
let n2_len = n2.digits.len();
|
||||
if n2_len > n1_len {
|
||||
return Ok((Number::from(0), n2));
|
||||
}
|
||||
let sign = match (n1.sign, n2.sign) {
|
||||
let dividend_len = dividend.digits.len();
|
||||
let divisor_len = divisor.digits.len();
|
||||
let sign = match (dividend.sign, divisor.sign) {
|
||||
(Sign::Positif, Sign::Positif) | (Sign::Negatif, Sign::Negatif) => Sign::Positif,
|
||||
(Sign::Positif, Sign::Negatif) | (Sign::Negatif, Sign::Positif) => Sign::Negatif,
|
||||
};
|
||||
let dividend = n1.digits[..n2_len].to_vec();
|
||||
let mut quotient = vec![];
|
||||
let mut remainder = Number {
|
||||
digits: dividend.clone(),
|
||||
let mut dividend = Number {
|
||||
digits: dividend.digits,
|
||||
sign: Sign::Positif,
|
||||
};
|
||||
let mut iteration = 1;
|
||||
let divisor = Number {
|
||||
digits: divisor.digits,
|
||||
sign: Sign::Positif,
|
||||
};
|
||||
match (sign, dividend.cmp(&divisor)) {
|
||||
(_, std::cmp::Ordering::Less) => return Ok((Number::from(0), dividend)),
|
||||
(Sign::Positif, std::cmp::Ordering::Equal) => {
|
||||
return Ok((Number::from(1), Number::from(0)))
|
||||
}
|
||||
(Sign::Negatif, std::cmp::Ordering::Equal) => {
|
||||
return Ok((Number::from(-1), Number::from(0)))
|
||||
}
|
||||
(_, std::cmp::Ordering::Greater) => (),
|
||||
}
|
||||
let mut quotient = vec![];
|
||||
let mut remainder = Number {
|
||||
digits: dividend
|
||||
.digits
|
||||
.drain((dividend_len - divisor_len)..)
|
||||
.collect(),
|
||||
sign: Sign::Positif,
|
||||
};
|
||||
|
||||
loop {
|
||||
while remainder < divisor && !dividend.digits.is_empty() {
|
||||
remainder.digits.insert(0, dividend.digits.pop().unwrap());
|
||||
quotient.push(0);
|
||||
}
|
||||
let mut factor = 0;
|
||||
loop {
|
||||
let temp_remainder = remainder.clone() - n2.clone();
|
||||
let temp_remainder = remainder.clone() - divisor.clone();
|
||||
if temp_remainder.sign == Sign::Negatif {
|
||||
quotient.push(factor);
|
||||
break;
|
||||
@ -43,13 +67,11 @@ impl Number {
|
||||
}
|
||||
remainder = temp_remainder;
|
||||
}
|
||||
if n1_len == n2_len + iteration - 1 {
|
||||
if dividend.digits.is_empty() {
|
||||
break;
|
||||
}
|
||||
remainder.digits.push(n1.digits[n2_len + iteration - 1]);
|
||||
iteration += 1;
|
||||
remainder.digits.insert(0, dividend.digits.pop().unwrap());
|
||||
}
|
||||
println!("{quotient:?}");
|
||||
for digit in quotient.clone() {
|
||||
if digit != 0 || quotient.len() == 1 {
|
||||
break;
|
||||
@ -70,27 +92,6 @@ impl Number {
|
||||
remainder.digits.pop();
|
||||
}
|
||||
Ok((res, remainder))
|
||||
//if n2 == 0.into() {
|
||||
// return Err(Box::from("Division by 0"));
|
||||
//}
|
||||
//let n1_len = n1.digits.len();
|
||||
//let n2_len = n2.digits.len();
|
||||
//if n2_len > n1_len {
|
||||
// return Ok((Number::from(0), n1));
|
||||
//}
|
||||
//let sign = match (n1.sign, n2.sign) {
|
||||
// (Sign::Positif, Sign::Positif) | (Sign::Negatif, Sign::Negatif) => Sign::Positif,
|
||||
// (Sign::Positif, Sign::Negatif) | (Sign::Negatif, Sign::Positif) => Sign::Negatif,
|
||||
//};
|
||||
//let mut res = Number::from(0);
|
||||
//let mut remainder = n1;
|
||||
|
||||
//loop {}
|
||||
|
||||
//if res.digits != vec![0] {
|
||||
// res.sign = sign;
|
||||
//}
|
||||
//Ok((res, remainder))
|
||||
}
|
||||
|
||||
pub fn gcd(mut a: Number, mut b: Number) -> Number {
|
||||
@ -202,6 +203,14 @@ mod test_number_div_rem {
|
||||
|
||||
#[test]
|
||||
fn div_rem_eleven_x_eleven() {
|
||||
let a = Number::from(11);
|
||||
let b = Number::from(11);
|
||||
let res = (Number::from(1), Number::from(0));
|
||||
assert_eq!(res, Number::div_with_rem(a, b).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div_rem_ten_x_eleven() {
|
||||
let a = Number::from(10);
|
||||
let b = Number::from(11);
|
||||
let res = (Number::from(0), Number::from(10));
|
||||
@ -210,17 +219,25 @@ mod test_number_div_rem {
|
||||
|
||||
#[test]
|
||||
fn div_rem_big_1() {
|
||||
//let a = Number::from("123");
|
||||
//let b = Number::from("32");
|
||||
//let res = (Number::from(3), Number::from(27));
|
||||
//assert_eq!(res, Number::div_with_rem(a, b).unwrap());
|
||||
let a = Number::from("123");
|
||||
let b = Number::from("32");
|
||||
let res = (Number::from(3), Number::from(27));
|
||||
assert_eq!(res, Number::div_with_rem(a, b).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div_rem_big_2() {
|
||||
//let a = Number::from("123456789");
|
||||
//let b = Number::from("123");
|
||||
//let res = (Number::from(1003713), Number::from(90));
|
||||
//assert_eq!(res, Number::div_with_rem(a, b).unwrap());
|
||||
let a = Number::from("123456789");
|
||||
let b = Number::from("123");
|
||||
let res = (Number::from(1003713), Number::from(90));
|
||||
assert_eq!(res, Number::div_with_rem(a, b).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div_rem_big_3() {
|
||||
let a = Number::from("1010101010");
|
||||
let b = Number::from("1010");
|
||||
let res = (Number::from(1000100), Number::from(10));
|
||||
assert_eq!(res, Number::div_with_rem(a, b).unwrap());
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ impl Ord for Number {
|
||||
Sign::Negatif => Ordering::Less,
|
||||
},
|
||||
Ordering::Equal => {
|
||||
for pair in zip(&self.digits, &other.digits) {
|
||||
for pair in zip(&self.digits, &other.digits).rev() {
|
||||
return match pair.0.cmp(pair.1) {
|
||||
Ordering::Less => match self.sign {
|
||||
Sign::Positif => Ordering::Less,
|
||||
@ -113,4 +113,12 @@ mod test_number_ord {
|
||||
assert!(a > b);
|
||||
assert_eq!(Ordering::Greater, a.cmp(&b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmp_91_32() {
|
||||
let a = Number::from(91);
|
||||
let b = Number::from(32);
|
||||
assert!(a > b);
|
||||
assert_eq!(Ordering::Greater, a.cmp(&b));
|
||||
}
|
||||
}
|
||||
|
@ -205,4 +205,12 @@ mod test_number_sub {
|
||||
let res = Number::from(110);
|
||||
assert_eq!(res, a - b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_91_32() {
|
||||
let a = Number::from(91);
|
||||
let b = (32).into();
|
||||
let res = Number::from(59);
|
||||
assert_eq!(res, a - b);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user