use crate::math::mathtool::gcd_stein;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Fraction<T> {
p: T, q: T, }
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
}
}