Implement sign handling for addition and subtraction
All checks were successful
timw4mail/rusty-numbers/pipeline/head This commit looks good

This commit is contained in:
Timothy Warren 2020-03-24 13:26:00 -04:00
parent 70aa876500
commit 063f6ffa48
3 changed files with 43 additions and 10 deletions

View File

@ -123,14 +123,36 @@ impl BigInt {
a_digits a_digits
} }
} }
/// Determine the output sign given the two input signs and operation
fn get_sign(a: Self, b: Self, op: FracOp) -> Sign {
// -a + -b = -c
if op == FracOp::Addition && a.sign == Negative && b.sign == Negative {
return Negative;
}
// a - -b = c
if op == FracOp::Subtraction && a.sign == Positive && b.sign == Negative {
return Positive;
}
if a.sign != b.sign {
Negative
} else {
Positive
}
}
} }
impl Add for BigInt { impl Add for BigInt {
type Output = Self; type Output = Self;
// @TODO: handle signs
fn add(self, rhs: Self) -> Self::Output { fn add(self, rhs: Self) -> Self::Output {
if self.sign == Positive && rhs.sign == Negative { // If the sign of one input differs,
// subtraction is equivalent
if self.sign == Negative && rhs.sign == Positive {
return rhs - -self;
} else if self.sign == Positive && rhs.sign == Negative {
return self - -rhs; return self - -rhs;
} }
@ -161,6 +183,8 @@ impl Add for BigInt {
} }
} }
out.sign = Self::get_sign(self, rhs, FracOp::Addition);
out.trim_zeros(); out.trim_zeros();
out out
@ -170,11 +194,17 @@ impl Add for BigInt {
impl Sub for BigInt { impl Sub for BigInt {
type Output = Self; type Output = Self;
// @TODO: handle signs
fn sub(self, rhs: Self) -> Self::Output { fn sub(self, rhs: Self) -> Self::Output {
let digits = Self::get_digit_count(&self, &rhs); let digits = Self::get_digit_count(&self, &rhs);
let mut out = BigInt::with_capacity(digits); let mut out = BigInt::with_capacity(digits);
// Handle cases where addition makes more sense
if self.sign == Positive && rhs.sign == Negative {
return self + -rhs;
} else if self.sign == Negative && rhs.sign == Positive {
return -(rhs + -self);
}
let mut borrow = 0usize; let mut borrow = 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);
@ -199,6 +229,8 @@ impl Sub for BigInt {
} }
} }
out.sign = Self::get_sign(self, rhs, FracOp::Subtraction);
out.trim_zeros(); out.trim_zeros();
out out

View File

@ -21,6 +21,14 @@ pub enum Sign {
Negative, Negative,
} }
/// The type of mathematical operation
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum FracOp {
Addition,
Subtraction,
Other,
}
impl Default for Sign { impl Default for Sign {
fn default() -> Self { fn default() -> Self {
Sign::Positive Sign::Positive

View File

@ -61,13 +61,6 @@ macro_rules! frac {
}; };
} }
#[derive(Debug, Copy, Clone, PartialEq)]
enum FracOp {
Addition,
Subtraction,
Other,
}
impl<T: Unsigned> Frac<T> { impl<T: Unsigned> Frac<T> {
/// Create a new rational number from signed or unsigned arguments /// Create a new rational number from signed or unsigned arguments
/// ///