Mostly implemented fractions and doc improvements
This commit is contained in:
parent
aae00e2031
commit
fb92f5c463
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
Loading…
Reference in New Issue
Block a user