lib 0.0.2-alpha

LIB: Math and container utilities for Rust. Notice: study purpose, not production ready.
Documentation
use crate::math::mathtool::gcd_stein;

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Fraction<T> {
    p: T, //numerator
    q: T, //denominator
}

impl<T> Fraction<T> {
}
impl Fraction<i64> {
    pub const fn new(numerator: i64, denominator: i64) -> Self {
        if denominator == 0 {
            panic!("Denominator cannot be zero.");
        }

        let gcd = gcd_stein(numerator.abs(), denominator.abs());
        let mut p = numerator / gcd;
        let mut q = denominator / gcd;

        if q < 0 {
            p = -p;
            q = -q;
        }

        Self { p, q }
    }

    pub fn numerator(&self) -> i64 {
        self.p
    }

    pub fn denominator(&self) -> i64 {
        self.q
    }

    pub fn abs(&self) -> Self {
        Self {
            p: self.p.abs(),
            q: self.q,
        }
    }

    pub fn negate(&self) -> Self {
        Self {
            p: -self.p,
            q: self.q,
        }
    }

    pub fn add(&self, other: &Self) -> Self {
        let num = self.p * other.q + other.p * self.q;
        let den = self.q * other.q;
        Self::new(num, den)
    }

    pub fn subtract(&self, other: &Self) -> Self {
        let num = self.p * other.q - other.p * self.q;
        let den = self.q * other.q;
        Self::new(num, den)
    }

    pub fn multiply(&self, other: &Self) -> Self {
        let num = self.p * other.p;
        let den = self.q * other.q;
        Self::new(num, den)
    }

    pub fn divide(&self, other: &Self) -> Self {
        if other.p == 0 {
            panic!("Cannot divide by zero fraction.");
        }
        let num = self.p * other.q;
        let den = self.q * other.p;
        Self::new(num, den)
    }

    pub fn to_f64(&self) -> f64 {
        self.p as f64 / self.q as f64
    }

    pub fn to_i64(&self) -> i64 {
        self.p / self.q
    }
}