From fb92f5c463499db6cb2f7bc6e7825e20c78808da Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Tue, 18 Feb 2020 10:19:57 -0500 Subject: [PATCH] Mostly implemented fractions and doc improvements --- src/num.rs | 3 +++ src/rational.rs | 72 +++++++++++++++++++++++++++++++++++++++++++------ src/seq.rs | 2 +- 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/num.rs b/src/num.rs index 6a9ba7c..d776060 100644 --- a/src/num.rs +++ b/src/num.rs @@ -84,7 +84,10 @@ pub trait Signed: Int { #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum Sign { + /// Greater than zero, or zero Positive, + + /// Less than zero Negative, } diff --git a/src/rational.rs b/src/rational.rs index 1000804..384e8f7 100644 --- a/src/rational.rs +++ b/src/rational.rs @@ -22,17 +22,21 @@ pub struct Frac { } #[macro_export] +/// Create a `Frac` type with signed number literals macro_rules! frac { - ($n:literal / $d:literal) => { - frac($n, $d) + ($w:literal $n:literal / $d:literal) => { + frac!($w) + frac!($n / $d) }; ($n:literal / $d:literal) => { frac($n, $d) }; + ($w:literal) => { + frac($w, 1) + }; } -/// Create a new rational number -pub fn frac, U: Unsigned>(n: S, d: S) -> Frac { +/// Create a new rational number from unsigned integers +fn frac, U: Unsigned>(n: S, d: S) -> Frac { // Converting from signed to unsigned should always be safe // when using the absolute value, especially since I'm converting // between the same bit size @@ -97,6 +101,12 @@ impl> Mul for Frac { } } +impl> MulAssign for Frac { + fn mul_assign(&mut self, rhs: Self) { + *self = self.clone() * rhs + } +} + impl> Div for Frac { type Output = Self; @@ -109,6 +119,12 @@ impl> Div for Frac { } } +impl> DivAssign for Frac { + fn div_assign(&mut self, rhs: Self) { + *self = self.clone() / rhs + } +} + impl + Sub + Mul> Add for Frac { type Output = Self; @@ -145,14 +161,46 @@ impl + Sub + Mul> Add for } } -impl> Sub for Frac { +impl + Sub + Mul> AddAssign for Frac { + fn add_assign(&mut self, rhs: Self) { + *self = self.clone() + rhs + } +} + +impl + Mul> Sub for Frac { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { - let a = self; - let b = rhs; + let a = if self.numer >= rhs.numer { + self + } else { + rhs + }; + let b = if self.numer < rhs.numer { + self + } else { + rhs + }; - unimplemented!() + if a.denom != b.denom { + let numer = (a.numer * b.denom) - (b.numer * a.denom); + let denom = a.denom * b.denom; + let sign = Self::get_sign(a, b); + + return Self::new(numer, denom, sign); + } + + let numer = a.numer - b.numer; + let denom = a.denom; + let sign = Self::get_sign(a, b); + + Self::new(numer, denom, sign) + } +} + +impl + Mul> SubAssign for Frac { + fn sub_assign(&mut self, rhs: Self) { + *self = self.clone() - rhs } } @@ -186,6 +234,11 @@ mod tests { assert_eq!(frac!(5 / 6), frac!(1 / 3) + frac!(1 / 2)); } + #[test] + fn sub_test() { + assert_eq!(frac!(1/6), frac!(1 / 2) - frac!(1/3)); + } + #[test] fn macro_test() { let frac1 = frac!(1 / 3); @@ -195,5 +248,8 @@ mod tests { let frac1 = -frac!(1 / 2); let frac2 = Frac::new(1u32, 2, Sign::Negative); assert_eq!(frac1, frac2); + + assert_eq!(frac!(3 / 2), frac!(1 1/2)); + assert_eq!(frac!(3 / 1), frac!(3)); } } diff --git a/src/seq.rs b/src/seq.rs index 655e90b..c3c758f 100644 --- a/src/seq.rs +++ b/src/seq.rs @@ -50,7 +50,7 @@ fn _fibonacci(n: usize, table: &mut Vec) -> Option { /// /// Example: /// ```rust -/// use rusty_numbers::seq::{factorial, fibonacci}; +/// use rusty_numbers::seq::factorial; /// /// let valid = factorial(3); // Some(6) /// # assert_eq!(6, valid.unwrap());