1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
use std::ops::*;
pub struct Rational
{
n: i64,
d: i64
}
fn gcd(a: i64, b: i64) -> i64
{match b { 0 => a, _ => gcd(b, a % b) }}
impl Default for Rational
{
fn default() -> Rational { Rational::from_int(0) }
}
impl Add for Rational
{
type Output = Self;
fn add(self, other: Self) -> Self
{
let c = gcd(self.d, other.d);
Rational{n: self.n * (other.d / c) + other.n * (self.d / c),
d: self.d / c * other.d}.reduced()
}
}
impl AddAssign for Rational
{
fn add_assign(&mut self, other: Self)
{
let c = gcd(self.d, other.d);
*self = Rational{n: self.n * (other.d / c) + other.n * (self.d / c),
d: self.d / c * other.d}.reduced()
}
}
impl Mul for Rational
{
type Output = Self;
fn mul(self, other: Self) -> Self
{
Rational{n: self.n * other.n, d: self.d * other.d}.reduced()
}
}
impl Div for Rational
{
type Output = Self;
fn div(self, other: Self) -> Self
{
Rational{n: self.n * other.d, d: self.d * other.n}.reduced()
}
}
impl From<u32> for Rational
{
fn from(v: u32) -> Self { Rational::from_int(v as i64) }
}
impl From<u16> for Rational
{
fn from(v: u16) -> Self { Rational::from_int(v as i64) }
}
impl From<u8> for Rational
{
fn from(v: u8) -> Self { Rational::from_int(v as i64) }
}
impl Rational
{
fn from_int(v: i64) -> Rational {Rational{n: v, d: 1}}
fn reduced(self) -> Rational
{
let c = gcd(self.n, self.d);
Rational{n: self.n / c, d: self.d / c}
}
fn as_int_trunc(self) -> i64 {self.n / self.d}
fn as_int_round(self) -> i64 {(self.n as f64 / self.d as f64).round() as i64}
}
|