feat(maths): basic ops overloading

This commit is contained in:
gbrochar 2023-08-03 12:16:17 +02:00
parent 8e3ebcd2a5
commit 22d9225235
2 changed files with 77 additions and 4 deletions

View File

@ -9,7 +9,7 @@ fn gcd(a: i128, b: i128) -> i128 {
}
}
#[derive(Debug, PartialEq, Clone)]
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Rational {
numerator: i128,
denominator: i128,
@ -27,6 +27,10 @@ impl Rational {
let gcd = gcd(self.numerator, self.denominator);
Rational::new(self.numerator / gcd, self.denominator / gcd)
}
pub fn inverse(&self) -> Self {
Rational::new(self.denominator, self.numerator)
}
}
impl ops::Add<Rational> for Rational {
@ -61,6 +65,22 @@ impl ops::Sub<Rational> for Rational {
}
}
impl ops::Sub<i128> for Rational {
type Output = Rational;
fn sub(self, rhs: i128) -> Rational {
Rational::new(self.numerator - rhs * self.denominator, self.denominator).reduce()
}
}
impl ops::Sub<Rational> for i128 {
type Output = Rational;
fn sub(self, rhs: Rational) -> Rational {
Rational::new(self * rhs.denominator - rhs.numerator, rhs.denominator).reduce()
}
}
impl ops::Mul<Rational> for Rational {
type Output = Rational;
@ -85,7 +105,32 @@ impl ops::Mul<Rational> for i128 {
}
}
#[derive(Debug, PartialEq, Clone)]
impl ops::Div<Rational> for Rational {
type Output = Rational;
fn div(self, rhs: Rational) -> Rational {
self * rhs.inverse()
}
}
impl ops::Div<i128> for Rational {
type Output = Rational;
fn div(self, rhs: i128) -> Rational {
let rhs_inverse = Rational::new(1, rhs);
self * rhs_inverse
}
}
impl ops::Div<Rational> for i128 {
type Output = Rational;
fn div(self, rhs: Rational) -> Rational {
self * rhs.inverse()
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct GaussianRational {
real: Rational,
imaginary: Rational,
@ -98,4 +143,32 @@ impl GaussianRational {
imaginary,
}
}
pub fn conjugate(&self) -> Self {
GaussianRational::new(self.real, -1 * self.imaginary)
}
}
impl ops::Add<GaussianRational> for GaussianRational {
type Output = GaussianRational;
fn add(self, rhs: GaussianRational) -> GaussianRational {
GaussianRational::new(self.real + rhs.real, self.imaginary + rhs.imaginary)
}
}
impl ops::Sub<GaussianRational> for GaussianRational {
type Output = GaussianRational;
fn sub(self, rhs: GaussianRational) -> GaussianRational {
GaussianRational::new(self.real - rhs.real, self.imaginary - rhs.imaginary)
}
}
impl ops::Mul<GaussianRational> for GaussianRational {
type Output = GaussianRational;
fn mul(self, rhs: GaussianRational) -> GaussianRational {
GaussianRational::new(self.real * rhs.real - self.imaginary * self.imaginary, self.real * rhs.imaginary + self.imaginary * rhs.real)
}
}

View File

@ -377,8 +377,8 @@ mod tests {
let tokens = vec![two_token(), plus(), two_token()];
let results = Node::Internal {
operator: plus(),
lhs: Box::new(Node::Leaf(vec![two.clone()])),
rhs: Box::new(Node::Leaf(vec![two.clone()]))
lhs: Box::new(Node::Leaf(vec![two])),
rhs: Box::new(Node::Leaf(vec![two]))
};
assert_eq!(build_ast(tokens), results);