Mostly implemented fractions and doc improvements

This commit is contained in:
Timothy Warren 2020-02-18 10:19:57 -05:00
parent aae00e2031
commit fb92f5c463
3 changed files with 68 additions and 9 deletions

View File

@ -84,7 +84,10 @@ pub trait Signed: Int {
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Sign { pub enum Sign {
/// Greater than zero, or zero
Positive, Positive,
/// Less than zero
Negative, Negative,
} }

View File

@ -22,17 +22,21 @@ pub struct Frac<T: Unsigned = usize> {
} }
#[macro_export] #[macro_export]
/// Create a `Frac` type with signed number literals
macro_rules! frac { macro_rules! frac {
($n:literal / $d:literal) => { ($w:literal $n:literal / $d:literal) => {
frac($n, $d) frac!($w) + frac!($n / $d)
}; };
($n:literal / $d:literal) => { ($n:literal / $d:literal) => {
frac($n, $d) frac($n, $d)
}; };
($w:literal) => {
frac($w, 1)
};
} }
/// Create a new rational number /// Create a new rational number from unsigned integers
pub fn frac<S: Signed + Signed<Un = U>, U: Unsigned>(n: S, d: S) -> Frac<U> { fn frac<S: Signed + Signed<Un = U>, U: Unsigned>(n: S, d: S) -> Frac<U> {
// Converting from signed to unsigned should always be safe // Converting from signed to unsigned should always be safe
// when using the absolute value, especially since I'm converting // when using the absolute value, especially since I'm converting
// between the same bit size // between the same bit size
@ -97,6 +101,12 @@ impl<T: Unsigned + Mul<Output = T>> Mul for Frac<T> {
} }
} }
impl<T: Unsigned + Mul<Output = T>> MulAssign for Frac<T> {
fn mul_assign(&mut self, rhs: Self) {
*self = self.clone() * rhs
}
}
impl<T: Unsigned + Mul<Output = T>> Div for Frac<T> { impl<T: Unsigned + Mul<Output = T>> Div for Frac<T> {
type Output = Self; type Output = Self;
@ -109,6 +119,12 @@ impl<T: Unsigned + Mul<Output = T>> Div for Frac<T> {
} }
} }
impl<T: Unsigned + Mul<Output = T>> DivAssign for Frac<T> {
fn div_assign(&mut self, rhs: Self) {
*self = self.clone() / rhs
}
}
impl<T: Unsigned + Add<Output = T> + Sub<Output = T> + Mul<Output = T>> Add for Frac<T> { impl<T: Unsigned + Add<Output = T> + Sub<Output = T> + Mul<Output = T>> Add for Frac<T> {
type Output = Self; type Output = Self;
@ -145,14 +161,46 @@ impl<T: Unsigned + Add<Output = T> + Sub<Output = T> + Mul<Output = T>> Add for
} }
} }
impl<T: Unsigned + Sub<Output = T>> Sub for Frac<T> { impl<T: Unsigned + Add<Output = T> + Sub<Output = T> + Mul<Output = T>> AddAssign for Frac<T> {
fn add_assign(&mut self, rhs: Self) {
*self = self.clone() + rhs
}
}
impl<T: Unsigned + Sub<Output = T> + Mul<Output = T>> Sub for Frac<T> {
type Output = Self; type Output = Self;
fn sub(self, rhs: Self) -> Self::Output { fn sub(self, rhs: Self) -> Self::Output {
let a = self; let a = if self.numer >= rhs.numer {
let b = rhs; 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<T: Unsigned + Sub<Output = T> + Mul<Output = T>> SubAssign for Frac<T> {
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)); 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] #[test]
fn macro_test() { fn macro_test() {
let frac1 = frac!(1 / 3); let frac1 = frac!(1 / 3);
@ -195,5 +248,8 @@ mod tests {
let frac1 = -frac!(1 / 2); let frac1 = -frac!(1 / 2);
let frac2 = Frac::new(1u32, 2, Sign::Negative); let frac2 = Frac::new(1u32, 2, Sign::Negative);
assert_eq!(frac1, frac2); assert_eq!(frac1, frac2);
assert_eq!(frac!(3 / 2), frac!(1 1/2));
assert_eq!(frac!(3 / 1), frac!(3));
} }
} }

View File

@ -50,7 +50,7 @@ fn _fibonacci(n: usize, table: &mut Vec<u128>) -> Option<u128> {
/// ///
/// Example: /// Example:
/// ```rust /// ```rust
/// use rusty_numbers::seq::{factorial, fibonacci}; /// use rusty_numbers::seq::factorial;
/// ///
/// let valid = factorial(3); // Some(6) /// let valid = factorial(3); // Some(6)
/// # assert_eq!(6, valid.unwrap()); /// # assert_eq!(6, valid.unwrap());