Fixed div now all arithmetic operations should work
This commit is contained in:
parent
1e0f6fd077
commit
9f10cee3e0
@ -7,30 +7,58 @@ use std::{
|
|||||||
use super::{Number, Sign};
|
use super::{Number, Sign};
|
||||||
|
|
||||||
impl Number {
|
impl Number {
|
||||||
pub fn div_with_rem(n1: Number, n2: Number) -> Result<(Number, Number), Box<dyn Error>> {
|
pub fn div_with_rem(
|
||||||
if n2 == 0.into() {
|
dividend: Number,
|
||||||
|
divisor: Number,
|
||||||
|
) -> Result<(Number, Number), Box<dyn Error>> {
|
||||||
|
if divisor == 0.into() {
|
||||||
return Err(Box::from("Division by 0"));
|
return Err(Box::from("Division by 0"));
|
||||||
}
|
}
|
||||||
let n1_len = n1.digits.len();
|
let dividend_len = dividend.digits.len();
|
||||||
let n2_len = n2.digits.len();
|
let divisor_len = divisor.digits.len();
|
||||||
if n2_len > n1_len {
|
let sign = match (dividend.sign, divisor.sign) {
|
||||||
return Ok((Number::from(0), n2));
|
|
||||||
}
|
|
||||||
let sign = match (n1.sign, n2.sign) {
|
|
||||||
(Sign::Positif, Sign::Positif) | (Sign::Negatif, Sign::Negatif) => Sign::Positif,
|
(Sign::Positif, Sign::Positif) | (Sign::Negatif, Sign::Negatif) => Sign::Positif,
|
||||||
(Sign::Positif, Sign::Negatif) | (Sign::Negatif, Sign::Positif) => Sign::Negatif,
|
(Sign::Positif, Sign::Negatif) | (Sign::Negatif, Sign::Positif) => Sign::Negatif,
|
||||||
};
|
};
|
||||||
let dividend = n1.digits[..n2_len].to_vec();
|
let mut dividend = Number {
|
||||||
let mut quotient = vec![];
|
digits: dividend.digits,
|
||||||
let mut remainder = Number {
|
|
||||||
digits: dividend.clone(),
|
|
||||||
sign: Sign::Positif,
|
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 {
|
loop {
|
||||||
|
while remainder < divisor && !dividend.digits.is_empty() {
|
||||||
|
remainder.digits.insert(0, dividend.digits.pop().unwrap());
|
||||||
|
quotient.push(0);
|
||||||
|
}
|
||||||
let mut factor = 0;
|
let mut factor = 0;
|
||||||
loop {
|
loop {
|
||||||
let temp_remainder = remainder.clone() - n2.clone();
|
if remainder.digits.iter().max().unwrap() == &0 {
|
||||||
|
quotient.push(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let temp_remainder = remainder.clone() - divisor.clone();
|
||||||
if temp_remainder.sign == Sign::Negatif {
|
if temp_remainder.sign == Sign::Negatif {
|
||||||
quotient.push(factor);
|
quotient.push(factor);
|
||||||
break;
|
break;
|
||||||
@ -43,13 +71,11 @@ impl Number {
|
|||||||
}
|
}
|
||||||
remainder = temp_remainder;
|
remainder = temp_remainder;
|
||||||
}
|
}
|
||||||
if n1_len == n2_len + iteration - 1 {
|
if dividend.digits.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
remainder.digits.push(n1.digits[n2_len + iteration - 1]);
|
remainder.digits.insert(0, dividend.digits.pop().unwrap());
|
||||||
iteration += 1;
|
|
||||||
}
|
}
|
||||||
println!("{quotient:?}");
|
|
||||||
for digit in quotient.clone() {
|
for digit in quotient.clone() {
|
||||||
if digit != 0 || quotient.len() == 1 {
|
if digit != 0 || quotient.len() == 1 {
|
||||||
break;
|
break;
|
||||||
@ -70,27 +96,6 @@ impl Number {
|
|||||||
remainder.digits.pop();
|
remainder.digits.pop();
|
||||||
}
|
}
|
||||||
Ok((res, remainder))
|
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 {
|
pub fn gcd(mut a: Number, mut b: Number) -> Number {
|
||||||
@ -202,6 +207,14 @@ mod test_number_div_rem {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn div_rem_eleven_x_eleven() {
|
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 a = Number::from(10);
|
||||||
let b = Number::from(11);
|
let b = Number::from(11);
|
||||||
let res = (Number::from(0), Number::from(10));
|
let res = (Number::from(0), Number::from(10));
|
||||||
@ -210,17 +223,33 @@ mod test_number_div_rem {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn div_rem_big_1() {
|
fn div_rem_big_1() {
|
||||||
//let a = Number::from("123");
|
let a = Number::from("123");
|
||||||
//let b = Number::from("32");
|
let b = Number::from("32");
|
||||||
//let res = (Number::from(3), Number::from(27));
|
let res = (Number::from(3), Number::from(27));
|
||||||
//assert_eq!(res, Number::div_with_rem(a, b).unwrap());
|
assert_eq!(res, Number::div_with_rem(a, b).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn div_rem_big_2() {
|
fn div_rem_big_2() {
|
||||||
//let a = Number::from("123456789");
|
let a = Number::from("123456789");
|
||||||
//let b = Number::from("123");
|
let b = Number::from("123");
|
||||||
//let res = (Number::from(1003713), Number::from(90));
|
let res = (Number::from(1003713), Number::from(90));
|
||||||
//assert_eq!(res, Number::div_with_rem(a, b).unwrap());
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn div_rem_small() {
|
||||||
|
let a = Number::from(10);
|
||||||
|
let b = Number::from(1);
|
||||||
|
let res = (Number::from(10), Number::from(0));
|
||||||
|
assert_eq!(res, Number::div_with_rem(a, b).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ impl Ord for Number {
|
|||||||
Sign::Negatif => Ordering::Less,
|
Sign::Negatif => Ordering::Less,
|
||||||
},
|
},
|
||||||
Ordering::Equal => {
|
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) {
|
return match pair.0.cmp(pair.1) {
|
||||||
Ordering::Less => match self.sign {
|
Ordering::Less => match self.sign {
|
||||||
Sign::Positif => Ordering::Less,
|
Sign::Positif => Ordering::Less,
|
||||||
@ -113,4 +113,12 @@ mod test_number_ord {
|
|||||||
assert!(a > b);
|
assert!(a > b);
|
||||||
assert_eq!(Ordering::Greater, a.cmp(&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);
|
let res = Number::from(110);
|
||||||
assert_eq!(res, a - b);
|
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