102 lines
2.3 KiB
Rust
102 lines
2.3 KiB
Rust
|
use std::ops;
|
||
|
|
||
|
//TODO slow ? check Stein's algorithm (binaryGCD)
|
||
|
fn gcd(a: i128, b: i128) -> i128 {
|
||
|
if b == 0 {
|
||
|
a
|
||
|
} else {
|
||
|
gcd(b, a % b)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, PartialEq, Clone)]
|
||
|
pub struct Rational {
|
||
|
numerator: i128,
|
||
|
denominator: i128,
|
||
|
}
|
||
|
|
||
|
impl Rational {
|
||
|
pub fn new(numerator: i128, denominator: i128) -> Self {
|
||
|
Self {
|
||
|
numerator,
|
||
|
denominator,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn reduce(&self) -> Self {
|
||
|
let gcd = gcd(self.numerator, self.denominator);
|
||
|
Rational::new(self.numerator / gcd, self.denominator / gcd)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Add<Rational> for Rational {
|
||
|
type Output = Rational;
|
||
|
|
||
|
fn add(self, rhs: Rational) -> Rational {
|
||
|
Rational::new(self.numerator * rhs.denominator + rhs.numerator * self.denominator, self.denominator * rhs.denominator).reduce()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Add<i128> for Rational {
|
||
|
type Output = Rational;
|
||
|
|
||
|
fn add(self, rhs: i128) -> Rational {
|
||
|
Rational::new(self.numerator + rhs * self.denominator, self.denominator).reduce()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Add<Rational> for i128 {
|
||
|
type Output = Rational;
|
||
|
|
||
|
fn add(self, rhs: Rational) -> Rational {
|
||
|
Rational::new(self * rhs.denominator + rhs.numerator, rhs.denominator).reduce()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Sub<Rational> for Rational {
|
||
|
type Output = Rational;
|
||
|
|
||
|
fn sub(self, rhs: Rational) -> Rational {
|
||
|
Rational::new(self.numerator * rhs.denominator - rhs.numerator * self.denominator, self.denominator * rhs.denominator).reduce()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Mul<Rational> for Rational {
|
||
|
type Output = Rational;
|
||
|
|
||
|
fn mul(self, rhs: Rational) -> Rational {
|
||
|
Rational::new(self.numerator * rhs.numerator, self.denominator * rhs.denominator).reduce()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Mul<i128> for Rational {
|
||
|
type Output = Rational;
|
||
|
|
||
|
fn mul(self, rhs: i128) -> Rational {
|
||
|
Rational::new(self.numerator * rhs, self.denominator).reduce()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Mul<Rational> for i128 {
|
||
|
type Output = Rational;
|
||
|
|
||
|
fn mul(self, rhs: Rational) -> Rational {
|
||
|
Rational::new(self * rhs.numerator, rhs.denominator).reduce()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, PartialEq, Clone)]
|
||
|
pub struct GaussianRational {
|
||
|
real: Rational,
|
||
|
imaginary: Rational,
|
||
|
}
|
||
|
|
||
|
impl GaussianRational {
|
||
|
pub fn new(real: Rational, imaginary: Rational) -> Self {
|
||
|
Self {
|
||
|
real,
|
||
|
imaginary,
|
||
|
}
|
||
|
}
|
||
|
}
|