Test zeros for addition
timw4mail/rusty-numbers/pipeline/head This commit looks good Details

This commit is contained in:
Timothy Warren 2020-03-11 13:58:56 -04:00
parent 9f60706a9b
commit a5b727a156
1 changed files with 55 additions and 20 deletions

View File

@ -77,6 +77,11 @@ impl BigInt {
trailing_zeros += 1; trailing_zeros += 1;
} }
// Always keep at least one digit
if trailing_zeros == current_len {
trailing_zeros -= 1;
}
let new_len = current_len - trailing_zeros; let new_len = current_len - trailing_zeros;
self.inner.truncate(new_len); self.inner.truncate(new_len);
@ -94,6 +99,23 @@ impl BigInt {
pub fn from_str_radix<T: ToString>(s: T, radix: usize) -> BigInt { pub fn from_str_radix<T: ToString>(s: T, radix: usize) -> BigInt {
todo!(); todo!();
} }
fn get_digit_count(a: &Self, b: &Self) -> usize {
let a_digits = a.inner.len();
let b_digits = b.inner.len();
let digits = if b_digits > a_digits {
b_digits
} else {
a_digits
};
if digits > 0 {
digits
} else {
1
}
}
} }
impl Add for BigInt { impl Add for BigInt {
@ -107,21 +129,20 @@ impl Add for BigInt {
let mut out = BigInt::new_empty(); let mut out = BigInt::new_empty();
let u_digits = self.inner.len(); let digits = Self::get_digit_count(&self, &rhs) + 1;
let v_digits = rhs.inner.len();
let digits = if v_digits > u_digits {
v_digits
} else {
u_digits
};
let mut carry = 0usize; let mut carry = 0usize;
for i in 0..=digits { for i in 0..digits {
let a = *self.inner.get(i).unwrap_or(&0usize); let a = *self.inner.get(i).unwrap_or(&0usize);
let b = *rhs.inner.get(i).unwrap_or(&0usize); let b = *rhs.inner.get(i).unwrap_or(&0usize);
let (res, overflowed) = a.overflowing_add(b); let (res, overflowed) = a.overflowing_add(b);
if res == 0 && !overflowed {
out.inner.push(res + carry);
carry = 0;
continue;
}
if overflowed { if overflowed {
out.inner.push(res + carry); out.inner.push(res + carry);
carry = 1; carry = 1;
@ -134,6 +155,8 @@ impl Add for BigInt {
} }
} }
out.trim_zeros();
out out
} }
} }
@ -145,14 +168,7 @@ impl Sub for BigInt {
// @TODO: handle signs // @TODO: handle signs
let mut out = BigInt::new_empty(); let mut out = BigInt::new_empty();
let u_digits = self.inner.len(); let digits = Self::get_digit_count(&self, &rhs);
let v_digits = rhs.inner.len();
let digits = if v_digits > u_digits {
v_digits
} else {
u_digits
};
let mut borrow = 0usize; let mut borrow = 0usize;
for i in 0..digits { for i in 0..digits {
@ -423,19 +439,38 @@ mod tests {
diff.inner[0], diff.inner[0],
core::usize::MAX - 1 core::usize::MAX - 1
); );
}
let a = BigInt { #[test]
fn test_sub_assign() {
let mut a = BigInt {
inner: vec![1,0,1], inner: vec![1,0,1],
sign: Positive sign: Positive
}; };
let b = BigInt::from(2); let b = BigInt::from(2);
let diff = a - b;
a -= b;
assert_eq!( assert_eq!(
diff.inner, a.inner,
vec![core::usize::MAX, core::usize::MAX] vec![core::usize::MAX, core::usize::MAX]
); );
} }
#[test]
fn test_zeros() {
let a = BigInt::new();
let b = BigInt::new();
// let c = a.clone() - b.clone();
// assert_eq!(a.clone(), b.clone());
// assert_eq!(c, a.clone());
let c = a.clone() + b.clone();
assert_eq!(a.clone(), b.clone());
assert_eq!(c, a.clone());
}
#[test] #[test]
fn test_not() { fn test_not() {
let a = BigInt::from(0u8); let a = BigInt::from(0u8);