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 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 for Rational { type Output = Rational; fn add(self, rhs: i128) -> Rational { Rational::new(self.numerator + rhs * self.denominator, self.denominator).reduce() } } impl ops::Add for i128 { type Output = Rational; fn add(self, rhs: Rational) -> Rational { Rational::new(self * rhs.denominator + rhs.numerator, rhs.denominator).reduce() } } impl ops::Sub 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 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 for Rational { type Output = Rational; fn mul(self, rhs: i128) -> Rational { Rational::new(self.numerator * rhs, self.denominator).reduce() } } impl ops::Mul 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, } } }