-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRational.h
87 lines (83 loc) · 2.33 KB
/
Rational.h
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
83
84
85
86
87
#define __Rational__
template <typename T>
class Rational {
void normalize() {
T g = gcd(numerator, denominator);
numerator /= g;
denominator /= g;
if (denominator < 0) {
numerator = -numerator;
denominator = -denominator;
}
}
static T _gcd(T a, T b) {
return b ? _gcd(b, a % b) : a;
}
public:
static T gcd(T a, T b) { return std::abs(_gcd(a, b)); }
T numerator;
T denominator;
Rational(T n = (T)0, T d = (T)1) : numerator(n), denominator(d) {};
operator bool() const { return numerator; }
Rational& operator+=(const Rational r) {
if (this == &r) {
if (denominator & 1) numerator *= 2;
else denominator /= 2;
return *this;
}
this->numerator *= r.denominator;
this->numerator += r.numerator * this->denominator;
this->denominator *= r.denominator;
normalize();
return *this;
}
Rational& operator-=(const Rational r) {
if (this == &r) {
numerator = 0;
denominator = 1;
return *this;
}
this->numerator *= r.denominator;
this->numerator -= r.numerator * this->denominator;
this->denominator *= r.denominator;
normalize();
return *this;
}
Rational& operator*=(const Rational r) {
if (this == &r) {
numerator *= numerator;
denominator *= denominator;
return *this;
}
this->numerator *= r.denominator;
this->denominator *= r.denominator;
normalize();
return *this;
}
};
#include <ostream>
template <typename T>
std::ostream& operator<<(std::ostream& o, const Rational<T>& r) {
return std::cout << "{" << r.numerator << "/" << r.denominator << "}";
}
template <typename T>
Rational<T> operator+(const Rational<T>& l, const Rational<T>& r) {
T n = l.numerator * r.denominator + r.numerator * l.denominator;
T d = l.denominator * r.denominator;
T g = Rational<T>::gcd(n, d);
return Rational<T>(n/g, d/g);
}
template <typename T>
Rational<T> operator-(const Rational<T>& l, const Rational<T>& r) {
T n = l.numerator * r.denominator - r.numerator * l.denominator;
T d = l.denominator * r.denominator;
T g = Rational<T>::gcd(n, d);
return Rational<T>(n / g, d / g);
}
template <typename T>
Rational<T> operator*(const Rational<T>& l, const Rational<T>& r) {
T n = l.numerator * r.numerator;
T d = l.denominator * r.denominator;
T g = Rational<T>::gcd(n, d);
return Rational<T>(n / g, d / g);
}