Added more tests and fixed add and sub
This commit is contained in:
parent
cad2d2b910
commit
1e0f6fd077
@ -78,6 +78,13 @@ impl Number {
|
|||||||
|
|
||||||
last_two.0
|
last_two.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn abs(self) -> Self {
|
||||||
|
Number {
|
||||||
|
digits: self.digits,
|
||||||
|
sign: Sign::Positif,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Number {
|
impl Display for Number {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
cmp::min,
|
cmp::{min, Ordering},
|
||||||
iter::zip,
|
iter::zip,
|
||||||
ops::{Add, AddAssign},
|
ops::{Add, AddAssign},
|
||||||
};
|
};
|
||||||
@ -14,6 +14,7 @@ impl Add for Number {
|
|||||||
let rhs_len = rhs.digits.len();
|
let rhs_len = rhs.digits.len();
|
||||||
let mut self_digits = self.digits.clone();
|
let mut self_digits = self.digits.clone();
|
||||||
let mut rhs_digits = rhs.digits.clone();
|
let mut rhs_digits = rhs.digits.clone();
|
||||||
|
let ord = self.clone().abs().cmp(&rhs.clone().abs());
|
||||||
if self_len != rhs_len {
|
if self_len != rhs_len {
|
||||||
let difference = (self_len).abs_diff(rhs_len);
|
let difference = (self_len).abs_diff(rhs_len);
|
||||||
let pad = vec![0i8; difference];
|
let pad = vec![0i8; difference];
|
||||||
@ -26,14 +27,24 @@ impl Add for Number {
|
|||||||
let zipped = zip(self_digits.iter(), rhs_digits.iter());
|
let zipped = zip(self_digits.iter(), rhs_digits.iter());
|
||||||
let mut carry = 0;
|
let mut carry = 0;
|
||||||
let mut digits = Vec::new();
|
let mut digits = Vec::new();
|
||||||
let mut sign = match (self.sign, rhs.sign) {
|
let sign = match (self.sign, rhs.sign, ord) {
|
||||||
(Sign::Positif, Sign::Positif) => Sign::Positif,
|
(Sign::Positif, Sign::Positif, _) => Sign::Positif,
|
||||||
(Sign::Negatif, Sign::Negatif) => Sign::Negatif,
|
(Sign::Negatif, Sign::Negatif, _) => Sign::Negatif,
|
||||||
(Sign::Positif, Sign::Negatif) | (Sign::Negatif, Sign::Positif) => Sign::Positif,
|
(Sign::Positif, Sign::Negatif, Ordering::Greater) => Sign::Positif,
|
||||||
|
(Sign::Positif, Sign::Negatif, Ordering::Less) => Sign::Negatif,
|
||||||
|
(Sign::Negatif, Sign::Positif, Ordering::Greater) => Sign::Negatif,
|
||||||
|
(Sign::Negatif, Sign::Positif, Ordering::Less) => Sign::Positif,
|
||||||
|
(Sign::Positif, Sign::Negatif, Ordering::Equal)
|
||||||
|
| (Sign::Negatif, Sign::Positif, Ordering::Equal) => Sign::Positif,
|
||||||
};
|
};
|
||||||
for (a, b) in zipped {
|
for (a, b) in zipped {
|
||||||
let comb = match (self.sign, rhs.sign) {
|
let comb = match (self.sign, rhs.sign, ord) {
|
||||||
(Sign::Positif, Sign::Positif) => {
|
(Sign::Positif, Sign::Negatif, Ordering::Equal)
|
||||||
|
| (Sign::Negatif, Sign::Positif, Ordering::Equal) => {
|
||||||
|
digits.push(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(Sign::Positif, Sign::Positif, _) | (Sign::Negatif, Sign::Negatif, _) => {
|
||||||
let comb = a + b + carry;
|
let comb = a + b + carry;
|
||||||
if comb > 9 {
|
if comb > 9 {
|
||||||
carry = 1;
|
carry = 1;
|
||||||
@ -42,43 +53,32 @@ impl Add for Number {
|
|||||||
}
|
}
|
||||||
comb % 10
|
comb % 10
|
||||||
}
|
}
|
||||||
(Sign::Positif, Sign::Negatif) => {
|
(Sign::Positif, Sign::Negatif, Ordering::Greater)
|
||||||
|
| (Sign::Negatif, Sign::Positif, Ordering::Greater) => {
|
||||||
|
let comb = if b > &(a - carry) {
|
||||||
|
let comb = a + 10 - b - carry;
|
||||||
|
carry = 1;
|
||||||
|
comb
|
||||||
|
} else {
|
||||||
let comb = a - b - carry;
|
let comb = a - b - carry;
|
||||||
if comb > 0 && b > a {
|
|
||||||
carry = 1;
|
|
||||||
} else {
|
|
||||||
carry = 0;
|
carry = 0;
|
||||||
}
|
comb
|
||||||
if b > a {
|
};
|
||||||
sign = Sign::Negatif;
|
|
||||||
} else {
|
|
||||||
sign = Sign::Positif;
|
|
||||||
}
|
|
||||||
(comb % 10).abs()
|
(comb % 10).abs()
|
||||||
}
|
}
|
||||||
(Sign::Negatif, Sign::Positif) => {
|
(Sign::Positif, Sign::Negatif, Ordering::Less)
|
||||||
let comb = -a + b - carry;
|
| (Sign::Negatif, Sign::Positif, Ordering::Less) => {
|
||||||
if comb > 0 && a > b {
|
let comb = if a > &(b - carry) {
|
||||||
|
let comb = b + 10 - a - carry;
|
||||||
carry = 1;
|
carry = 1;
|
||||||
|
comb
|
||||||
} else {
|
} else {
|
||||||
|
let comb = b - a - carry;
|
||||||
carry = 0;
|
carry = 0;
|
||||||
}
|
comb
|
||||||
if a > b {
|
};
|
||||||
sign = Sign::Negatif;
|
|
||||||
} else {
|
|
||||||
sign = Sign::Positif;
|
|
||||||
}
|
|
||||||
(comb % 10).abs()
|
(comb % 10).abs()
|
||||||
}
|
}
|
||||||
(Sign::Negatif, Sign::Negatif) => {
|
|
||||||
let comb = a + b + carry;
|
|
||||||
if comb > 9 {
|
|
||||||
carry = 1;
|
|
||||||
} else {
|
|
||||||
carry = 0;
|
|
||||||
}
|
|
||||||
comb % 10
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
digits.push(comb);
|
digits.push(comb);
|
||||||
}
|
}
|
||||||
@ -87,6 +87,13 @@ impl Add for Number {
|
|||||||
digits.push(carry);
|
digits.push(carry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for &digit in digits.clone().iter().rev() {
|
||||||
|
if digit != 0 || digits.len() == 1 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
digits.pop();
|
||||||
|
}
|
||||||
|
|
||||||
Self { digits, sign }
|
Self { digits, sign }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,13 +111,21 @@ mod test_number_add {
|
|||||||
use crate::number::Number;
|
use crate::number::Number;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_positif() {
|
fn add_positif_1() {
|
||||||
let a = Number::from(1);
|
let a = Number::from(1);
|
||||||
let b = 1.into();
|
let b = 1.into();
|
||||||
let res = Number::from(2);
|
let res = Number::from(2);
|
||||||
assert_eq!(res, a + b);
|
assert_eq!(res, a + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_positif_2() {
|
||||||
|
let a = Number::from(9);
|
||||||
|
let b = 1.into();
|
||||||
|
let res = Number::from(10);
|
||||||
|
assert_eq!(res, a + b);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_large_positif() {
|
fn add_large_positif() {
|
||||||
let a = Number::from(9);
|
let a = Number::from(9);
|
||||||
@ -152,21 +167,36 @@ mod test_number_add {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_larger_positif_to_negatif() {
|
fn add_larger_positif_to_negatif_1() {
|
||||||
let a = Number::from(-1);
|
let a = Number::from(-1);
|
||||||
let b = (11).into();
|
let b = (11).into();
|
||||||
let res = Number::from(10);
|
let res = Number::from(10);
|
||||||
assert_eq!(res, a + b);
|
assert_eq!(res, a + b);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn add_larger_positif_to_negatif_2() {
|
||||||
|
let a = Number::from(-2);
|
||||||
|
let b = (11).into();
|
||||||
|
let res = Number::from(9);
|
||||||
|
assert_eq!(res, a + b);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_larger_negatif_to_positif() {
|
fn add_larger_negatif_to_positif_1() {
|
||||||
let a = Number::from(1);
|
let a = Number::from(1);
|
||||||
let b = (-11).into();
|
let b = (-11).into();
|
||||||
let res = Number::from(-10);
|
let res = Number::from(-10);
|
||||||
assert_eq!(res, a + b);
|
assert_eq!(res, a + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_larger_negatif_to_positif_2() {
|
||||||
|
let a = Number::from(2);
|
||||||
|
let b = (-11).into();
|
||||||
|
let res = Number::from(-9);
|
||||||
|
assert_eq!(res, a + b);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_positif_to_larger_negatif() {
|
fn add_positif_to_larger_negatif() {
|
||||||
let a = Number::from(-99);
|
let a = Number::from(-99);
|
||||||
|
@ -123,6 +123,14 @@ mod test_number_mul {
|
|||||||
assert_eq!(res, a * b);
|
assert_eq!(res, a * b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mul_999_x_999() {
|
||||||
|
let a = Number::from(999);
|
||||||
|
let b = Number::from(999);
|
||||||
|
let res = Number::from(998001);
|
||||||
|
assert_eq!(res, a * b);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mul_big_1() {
|
fn mul_big_1() {
|
||||||
let a = Number::from("123");
|
let a = Number::from("123");
|
||||||
|
@ -46,6 +46,8 @@ impl Ord for Number {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_number_ord {
|
mod test_number_ord {
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use crate::number::Number;
|
use crate::number::Number;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -53,6 +55,7 @@ mod test_number_ord {
|
|||||||
let a = Number::from(1);
|
let a = Number::from(1);
|
||||||
let b = Number::from(1);
|
let b = Number::from(1);
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
|
assert_eq!(Ordering::Equal, a.cmp(&b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -60,6 +63,7 @@ mod test_number_ord {
|
|||||||
let a = Number::from(-1);
|
let a = Number::from(-1);
|
||||||
let b = Number::from(-1);
|
let b = Number::from(-1);
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
|
assert_eq!(Ordering::Equal, a.cmp(&b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -67,6 +71,7 @@ mod test_number_ord {
|
|||||||
let a = Number::from(1);
|
let a = Number::from(1);
|
||||||
let b = Number::from(-1);
|
let b = Number::from(-1);
|
||||||
assert!(a > b);
|
assert!(a > b);
|
||||||
|
assert_eq!(Ordering::Greater, a.cmp(&b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -74,6 +79,7 @@ mod test_number_ord {
|
|||||||
let a = Number::from(-1);
|
let a = Number::from(-1);
|
||||||
let b = Number::from(1);
|
let b = Number::from(1);
|
||||||
assert!(a < b);
|
assert!(a < b);
|
||||||
|
assert_eq!(Ordering::Less, a.cmp(&b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -81,6 +87,7 @@ mod test_number_ord {
|
|||||||
let a = Number::from(-1);
|
let a = Number::from(-1);
|
||||||
let b = Number::from(-10);
|
let b = Number::from(-10);
|
||||||
assert!(a > b);
|
assert!(a > b);
|
||||||
|
assert_eq!(Ordering::Greater, a.cmp(&b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -88,6 +95,7 @@ mod test_number_ord {
|
|||||||
let a = Number::from(1);
|
let a = Number::from(1);
|
||||||
let b = Number::from(10);
|
let b = Number::from(10);
|
||||||
assert!(a < b);
|
assert!(a < b);
|
||||||
|
assert_eq!(Ordering::Less, a.cmp(&b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -95,6 +103,7 @@ mod test_number_ord {
|
|||||||
let a = Number::from(-10);
|
let a = Number::from(-10);
|
||||||
let b = Number::from(-1);
|
let b = Number::from(-1);
|
||||||
assert!(a < b);
|
assert!(a < b);
|
||||||
|
assert_eq!(Ordering::Less, a.cmp(&b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -102,5 +111,6 @@ mod test_number_ord {
|
|||||||
let a = Number::from(10);
|
let a = Number::from(10);
|
||||||
let b = Number::from(1);
|
let b = Number::from(1);
|
||||||
assert!(a > b);
|
assert!(a > b);
|
||||||
|
assert_eq!(Ordering::Greater, a.cmp(&b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
cmp::min,
|
cmp::{min, Ordering},
|
||||||
iter::zip,
|
iter::zip,
|
||||||
ops::{Sub, SubAssign},
|
ops::{Sub, SubAssign},
|
||||||
};
|
};
|
||||||
@ -14,6 +14,7 @@ impl Sub for Number {
|
|||||||
let rhs_len = rhs.digits.len();
|
let rhs_len = rhs.digits.len();
|
||||||
let mut self_digits = self.digits.clone();
|
let mut self_digits = self.digits.clone();
|
||||||
let mut rhs_digits = rhs.digits.clone();
|
let mut rhs_digits = rhs.digits.clone();
|
||||||
|
let ord = self.clone().abs().cmp(&rhs.clone().abs());
|
||||||
if self_len != rhs_len {
|
if self_len != rhs_len {
|
||||||
let difference = (self_len).abs_diff(rhs_len);
|
let difference = (self_len).abs_diff(rhs_len);
|
||||||
let pad = vec![0i8; difference];
|
let pad = vec![0i8; difference];
|
||||||
@ -26,28 +27,24 @@ impl Sub for Number {
|
|||||||
let zipped = zip(self_digits.iter(), rhs_digits.iter());
|
let zipped = zip(self_digits.iter(), rhs_digits.iter());
|
||||||
let mut carry = 0;
|
let mut carry = 0;
|
||||||
let mut digits = Vec::new();
|
let mut digits = Vec::new();
|
||||||
let mut sign = match (self.sign, rhs.sign) {
|
let sign = match (self.sign, rhs.sign, ord) {
|
||||||
(Sign::Positif, Sign::Negatif) => Sign::Positif,
|
(Sign::Positif, Sign::Negatif, _) => Sign::Positif,
|
||||||
(Sign::Negatif, Sign::Positif) => Sign::Negatif,
|
(Sign::Negatif, Sign::Positif, _) => Sign::Negatif,
|
||||||
(Sign::Positif, Sign::Positif) | (Sign::Negatif, Sign::Negatif) => Sign::Positif,
|
(Sign::Positif, Sign::Positif, Ordering::Greater) => Sign::Positif,
|
||||||
|
(Sign::Positif, Sign::Positif, Ordering::Less) => Sign::Negatif,
|
||||||
|
(Sign::Negatif, Sign::Negatif, Ordering::Greater) => Sign::Negatif,
|
||||||
|
(Sign::Negatif, Sign::Negatif, Ordering::Less) => Sign::Positif,
|
||||||
|
(Sign::Positif, Sign::Positif, Ordering::Equal)
|
||||||
|
| (Sign::Negatif, Sign::Negatif, Ordering::Equal) => Sign::Positif,
|
||||||
};
|
};
|
||||||
for (a, b) in zipped {
|
for (a, b) in zipped {
|
||||||
let comb = match (self.sign, rhs.sign) {
|
let comb = match (self.sign, rhs.sign, ord) {
|
||||||
(Sign::Positif, Sign::Positif) => {
|
(Sign::Positif, Sign::Positif, Ordering::Equal)
|
||||||
let comb = a - b - carry;
|
| (Sign::Negatif, Sign::Negatif, Ordering::Equal) => {
|
||||||
if comb < 0 {
|
digits.push(0);
|
||||||
carry = 1;
|
break;
|
||||||
} else {
|
|
||||||
carry = 0;
|
|
||||||
}
|
}
|
||||||
if b > a {
|
(Sign::Positif, Sign::Negatif, _) | (Sign::Negatif, Sign::Positif, _) => {
|
||||||
sign = Sign::Negatif;
|
|
||||||
} else {
|
|
||||||
sign = Sign::Positif;
|
|
||||||
}
|
|
||||||
(comb % 10).abs()
|
|
||||||
}
|
|
||||||
(Sign::Positif, Sign::Negatif) => {
|
|
||||||
let comb = a + b + carry;
|
let comb = a + b + carry;
|
||||||
if comb > 9 {
|
if comb > 9 {
|
||||||
carry = 1;
|
carry = 1;
|
||||||
@ -56,36 +53,47 @@ impl Sub for Number {
|
|||||||
}
|
}
|
||||||
comb % 10
|
comb % 10
|
||||||
}
|
}
|
||||||
(Sign::Negatif, Sign::Positif) => {
|
(Sign::Positif, Sign::Positif, Ordering::Greater)
|
||||||
let comb = -a - b - carry;
|
| (Sign::Negatif, Sign::Negatif, Ordering::Greater) => {
|
||||||
if comb < -9 {
|
let comb = if b > &(a - carry) {
|
||||||
|
let comb = a + 10 - b - carry;
|
||||||
carry = 1;
|
carry = 1;
|
||||||
|
comb
|
||||||
} else {
|
} else {
|
||||||
|
let comb = a - b - carry;
|
||||||
carry = 0;
|
carry = 0;
|
||||||
}
|
comb
|
||||||
|
};
|
||||||
(comb % 10).abs()
|
(comb % 10).abs()
|
||||||
}
|
}
|
||||||
(Sign::Negatif, Sign::Negatif) => {
|
(Sign::Positif, Sign::Positif, Ordering::Less)
|
||||||
let comb = -a + b + carry;
|
| (Sign::Negatif, Sign::Negatif, Ordering::Less) => {
|
||||||
if comb > 10 {
|
let comb = if a > &(b - carry) {
|
||||||
|
let comb = b + 10 - a - carry;
|
||||||
carry = 1;
|
carry = 1;
|
||||||
|
comb
|
||||||
} else {
|
} else {
|
||||||
|
let comb = b - a - carry;
|
||||||
carry = 0;
|
carry = 0;
|
||||||
}
|
comb
|
||||||
if a > b {
|
};
|
||||||
sign = Sign::Negatif;
|
(comb % 10).abs()
|
||||||
} else {
|
|
||||||
sign = Sign::Positif;
|
|
||||||
}
|
|
||||||
comb % 10
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
digits.push(comb);
|
digits.push(comb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if carry != 0 {
|
if carry != 0 {
|
||||||
digits.push(carry);
|
digits.push(carry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for &digit in digits.clone().iter().rev() {
|
||||||
|
if digit != 0 || digits.len() == 1 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
digits.pop();
|
||||||
|
}
|
||||||
|
|
||||||
Self { digits, sign }
|
Self { digits, sign }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,6 +158,38 @@ mod test_number_sub {
|
|||||||
assert_eq!(res, a - b);
|
assert_eq!(res, a - b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sub_larger_positif_from_positif_1() {
|
||||||
|
let a = Number::from(1);
|
||||||
|
let b = (11).into();
|
||||||
|
let res = Number::from(-10);
|
||||||
|
assert_eq!(res, a - b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sub_larger_positif_from_positif_2() {
|
||||||
|
let a = Number::from(2);
|
||||||
|
let b = (11).into();
|
||||||
|
let res = Number::from(-9);
|
||||||
|
assert_eq!(res, a - b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sub_positif_from_larger_positif_1() {
|
||||||
|
let a = Number::from(11);
|
||||||
|
let b = (1).into();
|
||||||
|
let res = Number::from(10);
|
||||||
|
assert_eq!(res, a - b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sub_positif_from_larger_positif_2() {
|
||||||
|
let a = Number::from(11);
|
||||||
|
let b = (2).into();
|
||||||
|
let res = Number::from(9);
|
||||||
|
assert_eq!(res, a - b);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sub_positif_from_larger_negatif() {
|
fn sub_positif_from_larger_negatif() {
|
||||||
let a = Number::from(-99);
|
let a = Number::from(-99);
|
||||||
|
Loading…
Reference in New Issue
Block a user