Implement sign handling for addition and subtraction
All checks were successful
timw4mail/rusty-numbers/pipeline/head This commit looks good
All checks were successful
timw4mail/rusty-numbers/pipeline/head This commit looks good
This commit is contained in:
parent
70aa876500
commit
063f6ffa48
@ -123,14 +123,36 @@ impl BigInt {
|
||||
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 {
|
||||
type Output = Self;
|
||||
|
||||
// @TODO: handle signs
|
||||
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;
|
||||
}
|
||||
|
||||
@ -161,6 +183,8 @@ impl Add for BigInt {
|
||||
}
|
||||
}
|
||||
|
||||
out.sign = Self::get_sign(self, rhs, FracOp::Addition);
|
||||
|
||||
out.trim_zeros();
|
||||
|
||||
out
|
||||
@ -170,11 +194,17 @@ impl Add for BigInt {
|
||||
impl Sub for BigInt {
|
||||
type Output = Self;
|
||||
|
||||
// @TODO: handle signs
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
let digits = Self::get_digit_count(&self, &rhs);
|
||||
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;
|
||||
for i in 0..digits {
|
||||
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
|
||||
|
@ -21,6 +21,14 @@ pub enum Sign {
|
||||
Negative,
|
||||
}
|
||||
|
||||
/// The type of mathematical operation
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum FracOp {
|
||||
Addition,
|
||||
Subtraction,
|
||||
Other,
|
||||
}
|
||||
|
||||
impl Default for Sign {
|
||||
fn default() -> Self {
|
||||
Sign::Positive
|
||||
|
@ -61,13 +61,6 @@ macro_rules! frac {
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
enum FracOp {
|
||||
Addition,
|
||||
Subtraction,
|
||||
Other,
|
||||
}
|
||||
|
||||
impl<T: Unsigned> Frac<T> {
|
||||
/// Create a new rational number from signed or unsigned arguments
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user