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
|
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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user