View difference between Paste ID: Y0iWcfBC and LVhDFszP
SHOW: | | - or go back to the newest paste.
1
#include <iostream>
2
#include <numeric>
3
4
using namespace std;
5
6
class Rational {
7
public:
8
    Rational() = default;
9
10
    Rational(int value)
11
        : numerator_(value)
12
        , denominator_(1) {
13
    }
14
15
    Rational(int numerator, int denominator)
16
        : numerator_(numerator)
17
        , denominator_(denominator)
18
    {
19
        Normalize();
20
    }
21
22
    int Numerator() const {
23
        return numerator_;
24
    }
25
26
    int Denominator() const {
27
        return denominator_;
28
    }
29
30
    Rational& operator+=(Rational right) {
31
        numerator_ = numerator_ * right.denominator_ + right.numerator_ * denominator_;
32
        denominator_ *= right.denominator_;
33
        Normalize();
34
        return *this;
35
    }
36
37
    Rational& operator-=(Rational right) {
38
        numerator_ = numerator_ * right.denominator_ - right.numerator_ * denominator_;
39
        denominator_ *= right.denominator_;
40
        Normalize();
41
        return *this;
42
    }
43
44
    Rational& operator*=(Rational right) {
45
        numerator_ *= right.numerator_;
46
        denominator_ *= right.denominator_;
47
        Normalize();
48
        return *this;
49
    }
50
51
    Rational& operator/=(Rational right) {
52
        if(right.numerator_==0){
53
            throw invalid_argument("divisor is zero"s);
54
        }
55
        numerator_ *= right.denominator_;
56
        denominator_ *= right.numerator_;
57
        Normalize();
58
        return *this;
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
// Unary plus and minus
91
92
Rational operator+(Rational value) {
93
    return value;
94
}
95
96
Rational operator-(Rational value) {
97
    return {-value.Numerator(), value.Denominator()};
98
}
99
100
// Binary arithmetic operations
101
102
Rational operator+(Rational left, Rational right) {
103
    return left += right;
104
}
105
106
Rational operator-(Rational left, Rational right) {
107
    return left -= right;
108
}
109
110
Rational operator*(Rational left, Rational right) {
111
    return left *= right;
112
}
113
114
Rational operator/(Rational left, Rational right) {
115
    return left /= right;
116
}
117
118
// Comparison operators
119
120
bool operator==(Rational left, Rational right) {
121
    return left.Numerator() == right.Numerator() &&
122
           left.Denominator() == right.Denominator();
123
}
124
125
bool operator!=(Rational left, Rational right) {
126
    return !(left == right);
127
}
128
129
bool operator<(Rational left, Rational right) {
130
    return left.Numerator() * right.Denominator() < 
131
           left.Denominator() * right.Numerator();
132
}
133
134
bool operator>(Rational left, Rational right) {
135
    return left.Numerator() * right.Denominator() >
136
           left.Denominator() * right.Numerator();
137
}
138
139
bool operator>=(Rational left, Rational right) {
140
    return !(left < right);
141
}
142
143
bool operator<=(Rational left, Rational right) {
144
    return !(left > right);
145
}
146
147
int main() {
148
    try {
149
        const Rational three_fifth{3, 5};
150
        const Rational zero;
151
        cout << three_fifth << " / " << zero << " = " << (three_fifth / zero) << endl;
152
    } catch (const invalid_argument& e) {
153
        cout << "Ошибка: "s << e.what() << endl;
154
    }
155
    try {
156
        Rational value{3, 5};
157
        value /= Rational();
158
        // Следующая строка не должна выполниться
159
        cout << value << endl;
160
    } catch (const invalid_argument& e) {
161
        cout << "Ошибка: "s << e.what() << endl;
162
    }
163
} 
164