use std::borrow::Borrow;
use crate::primes::PrimeFactorization;
#[derive(Debug, Clone)]
pub struct Rational {
pub numerator: PrimeFactorization,
pub denominator: PrimeFactorization,
}
impl Rational {
pub fn new(mut numerator: PrimeFactorization, mut denominator: PrimeFactorization) -> Rational {
numerator.sign *= denominator.sign;
denominator.sign = 1;
return Rational {
numerator,
denominator,
};
}
pub fn simplify(&mut self) {
for (num_factor, den_factor) in self.numerator.factors.iter_mut().zip(self.denominator.factors.iter_mut()) {
let gcd = std::cmp::min(*num_factor, *den_factor);
*num_factor -= gcd;
*den_factor -= gcd;
}
self.numerator.simplify_factors();
self.denominator.simplify_factors();
}
pub fn as_f64(&self) -> f64 {
self.numerator.as_f64() / self.denominator.as_f64()
}
pub fn signed_root(&self) -> f64 {
let value = self.as_f64();
return value.signum() * value.abs().sqrt();
}
}
impl<T> std::ops::MulAssign<T> for Rational where T: Borrow<Rational> {
fn mul_assign(&mut self, rhs: T) {
let rhs = rhs.borrow();
debug_assert_eq!(self.denominator.sign, 1);
debug_assert_eq!(rhs.denominator.sign, 1);
self.numerator.sign *= rhs.numerator.sign;
self.numerator *= &rhs.numerator;
self.denominator *= &rhs.denominator;
}
}