Naive implementation of fractions in Rust
In this note arithmetic operations for fractions are implemented using Rust language. A two term structure is defined to represent numerator and denominator.
struct Frac {
a: i32, // numerator
b: i32, // denominator
}
With this structure, we are able to define fractions like the following examples:
let x = Frac{a: 6, b: 3};
let y = Frac{a: 2, b: 5};
println!("x = {}/{}", x.a, x.b);
println!("y = {}/{}", y.a, y.b);
A basic function that is required for fraction-arithmetic is one to find the greather commond denominator, as a way to represent fractions where numerator and denominator are simpler.
fn gcd(a: i32, b: i32) -> i32 {
if b == 0 { return a; }
let mut x = a;
let mut y = b;
if b > a {
let z = x;
x = y;
y = z;
}
return gcd(y, x % y);
}
Operations are defined inside a impl Frac { }
block, as follows:
// Sum operation
fn sum(&self, f: &Frac) -> Frac {
let num = &self.a * f.b + &self.b * f.a;
let den = &self.b * f.b;
return Frac{a: num, b: den}.reduce();
}
// Substract operation
fn sub(&self, f: &Frac) -> Frac {
let num = &self.a * f.b - &self.b * f.a;
let den = &self.b * f.b;
return Frac{a: num, b: den}.reduce();
}
// Multiplication
fn mul(&self, f: &Frac) -> Frac {
let num = &self.a * f.a;
let den = &self.b * f.b;
return Frac{a: num, b: den}.reduce();
}
// Division
fn div(&self, f: &Frac) -> Frac {
let num = &self.a * &f.b;
let den = &self.b * &f.a;
return Frac{a: num, b: den}.reduce();
}
The reduce
function called in every operation is the ones that uses
gcd
function to simplify a fraction:
fn reduce(&self) -> Frac {
let cd = gcd(self.a, self.b);
return Frac{a: &self.a / cd, b: &self.b / cd};
}
Here is the full program list:
// Arithmentic on fractions naive implementation
// A basic structure to represent fractions
struct Frac {
a: i32, // numerator
b: i32, // denominator
}
impl Frac {
// Sum operation
fn sum(&self, f: &Frac) -> Frac {
let num = &self.a * f.b + &self.b * f.a;
let den = &self.b * f.b;
return Frac{a: num, b: den}.reduce();
}
// Substract operation
fn sub(&self, f: &Frac) -> Frac {
let num = &self.a * f.b - &self.b * f.a;
let den = &self.b * f.b;
return Frac{a: num, b: den}.reduce();
}
// Multiplication
fn mul(&self, f: &Frac) -> Frac {
let num = &self.a * f.a;
let den = &self.b * f.b;
return Frac{a: num, b: den}.reduce();
}
// Division
fn div(&self, f: &Frac) -> Frac {
let num = &self.a * &f.b;
let den = &self.b * &f.a;
return Frac{a: num, b: den}.reduce();
}
// Reduce fraction with gcd
fn reduce(&self) -> Frac {
let cd = gcd(self.a, self.b);
return Frac{a: &self.a / cd, b: &self.b / cd};
}
}
// Greather Common Divisor
fn gcd(a: i32, b: i32) -> i32 {
if b == 0 { return a; }
let mut x = a;
let mut y = b;
if b > a {
let z = x;
x = y;
y = z;
}
return gcd(y, x % y);
}
fn main() {
// Two fractions to use as examples
let x = Frac{a: 6, b: 3};
let y = Frac{a: 2, b: 5};
println!("x = {}/{}", x.a, x.b);
println!("y = {}/{}", y.a, y.b);
// Operating over them
let r_sum = x.sum(&y);
let r_sub = x.sub(&y);
let r_mul = x.mul(&y);
let r_div = x.div(&y);
// Displaying results
println!("x + y = {}/{}", r_sum.a, r_sum.b);
println!("x - y = {}/{}", r_sub.a, r_sub.b);
println!("x * y = {}/{}", r_mul.a, r_mul.b);
println!("x / y = {}/{}", r_div.a, r_div.b);
}
The output of this program is:
x = 6/3
y = 2/5
x + y = 12/5
x - y = 8/5
x * y = 4/5
x / y = 5/1
Date: Dec. 29, 2023