View difference between Paste ID: gK2AXXA8 and ZhrU5hCs
SHOW: | | - or go back to the newest paste.
1
#include <iostream>
2
#include <numeric>
3
#include <string>
4
5
using namespace std;
6
7
class Rational {
8
public:
9
    Rational() = default;
10
11
    Rational(int value)
12
        : numerator_(value)
13
        , denominator_(1)
14
    {
15
    }
16
17
    Rational(int numerator, int denominator)
18
        : numerator_(numerator)
19
        , denominator_(denominator)
20
    {
21
        Normalize();
22
    }
23
24
    int Numerator() const {
25
        return numerator_;
26
    }
27
28
    int Denominator() const {
29
        return denominator_;
30
    }
31
    
32
    Rational& operator+=(Rational r) {
33
        numerator_ = numerator_ * r.Denominator() + denominator_ * r.Numerator();
34
        denominator_ = denominator_ * r.Denominator();
35
        Normalize();
36
        return *this;
37
    }
38
    
39
    Rational& operator-=(Rational r) {
40
        numerator_ = numerator_ * r.Denominator() - denominator_ * r.Numerator();
41
        denominator_ = denominator_ * r.Denominator();
42
        Normalize();
43
        return *this;
44
    }
45
    
46
    Rational& operator*=(Rational r) {
47
        numerator_ *= r.Numerator();
48
        denominator_ *= r.Denominator();
49
        Normalize();
50
        return *this;
51
    }
52
    
53
    Rational& operator/=(Rational r) {
54
        numerator_ *= r.Denominator();
55
        denominator_ *= r.Numerator();
56
        Normalize();
57
        return *this;
58
    }
59
    
60
61
private:
62
    void Normalize() {
63
        if (denominator_ < 0) {
64
            numerator_ = -numerator_;
65
            denominator_ = -denominator_;
66
        }
67
        int n = gcd(numerator_, denominator_);
68
        numerator_ /= n;
69
        denominator_ /= n;
70
    }
71
72
    int numerator_ = 0;
73
    int denominator_ = 1;
74
};
75
76
ostream& operator<<(ostream& output, Rational rational) {
77
    return output << rational.Numerator() << '/' << rational.Denominator();
78
}
79
80
istream& operator>>(istream& input, Rational& rational) {
81
    int numerator;
82
    int denominator;
83
    char slash;
84
    if ((input >> numerator) && (input >> slash) && (slash == '/') && (input >> denominator)) {
85
        rational = Rational{numerator, denominator};
86
    }
87
    return input;
88
}
89
90
Rational operator+(Rational left, Rational right) {
91
    const int numerator = left.Numerator() * right.Denominator() + right.Numerator() * left.Denominator();
92
    const int denominator = left.Denominator() * right.Denominator();
93
94
    return {numerator, denominator};
95
}
96
97
Rational operator-(Rational left, Rational right) {
98
    const int numerator = left.Numerator() * right.Denominator() - right.Numerator() * left.Denominator();
99
    const int denominator = left.Denominator() * right.Denominator();
100
101
    return {numerator, denominator};
102
}
103
104
105
Rational operator+(Rational value) {
106
    return value;
107
}
108
109
Rational operator-(Rational value) {
110
    return {-value.Numerator(), value.Denominator()};
111
}