Skip to content

Instantly share code, notes, and snippets.

@NTG-TPL
Created October 2, 2023 09:38
Show Gist options
  • Save NTG-TPL/b0486cbb02c41e805e134e91571f7c99 to your computer and use it in GitHub Desktop.
Save NTG-TPL/b0486cbb02c41e805e134e91571f7c99 to your computer and use it in GitHub Desktop.
C++ rational
#include <iostream>
#include <numeric>
#include <stdexcept>
using namespace std;
class Rational {
public:
Rational() = default;
Rational(int value)
: numerator_(value)
, denominator_(1) {
}
Rational(int numerator, int denominator)
: numerator_(numerator)
, denominator_(denominator)
{
if(denominator_ == 0){
throw domain_error("Попытка создать дробь с нулевым знаменателем");
}
Normalize();
}
int Numerator() const {
return numerator_;
}
int Denominator() const {
return denominator_;
}
Rational& operator+=(Rational right) {
numerator_ = numerator_ * right.denominator_ + right.numerator_ * denominator_;
denominator_ *= right.denominator_;
Normalize();
return *this;
}
Rational& operator-=(Rational right) {
numerator_ = numerator_ * right.denominator_ - right.numerator_ * denominator_;
denominator_ *= right.denominator_;
Normalize();
return *this;
}
Rational& operator*=(Rational right) {
numerator_ *= right.numerator_;
denominator_ *= right.denominator_;
Normalize();
return *this;
}
Rational& operator/=(Rational right) {
numerator_ *= right.denominator_;
denominator_ *= right.numerator_;
Normalize();
return *this;
}
private:
void Normalize() {
if (denominator_ < 0) {
numerator_ = -numerator_;
denominator_ = -denominator_;
}
int n = gcd(numerator_, denominator_);
if(denominator_ ==0 || n ==0){
throw invalid_argument("Деление на ноль");
}
numerator_ /= n;
denominator_ /= n;
}
int numerator_ = 0;
int denominator_ = 1;
};
ostream& operator<<(ostream& output, Rational rational) {
return output << rational.Numerator() << '/' << rational.Denominator();
}
istream& operator>>(istream& input, Rational& rational) {
int numerator;
int denominator;
char slash;
if ((input >> numerator) && (input >> slash) && (slash == '/') && (input >> denominator)) {
rational = Rational{numerator, denominator};
}
return input;
}
Rational operator+(Rational value) {
return value;
}
Rational operator-(Rational value) {
return {-value.Numerator(), value.Denominator()};
}
Rational operator+(Rational left, Rational right) {
return left += right;
}
Rational operator-(Rational left, Rational right) {
return left -= right;
}
Rational operator*(Rational left, Rational right) {
return left *= right;
}
Rational operator/(Rational left, Rational right) {
return left /= right;
}
bool operator==(Rational left, Rational right) {
return left.Numerator() == right.Numerator() &&
left.Denominator() == right.Denominator();
}
bool operator!=(Rational left, Rational right) {
return !(left == right);
}
bool operator<(Rational left, Rational right) {
return left.Numerator() * right.Denominator() <
left.Denominator() * right.Numerator();
}
bool operator>(Rational left, Rational right) {
return left.Numerator() * right.Denominator() >
left.Denominator() * right.Numerator();
}
bool operator>=(Rational left, Rational right) {
return !(left < right);
}
bool operator<=(Rational left, Rational right) {
return !(left > right);
}
int main() {
try {
const Rational invalid_value{1, 0};
cout << invalid_value << endl;
} catch (const domain_error& e) {
cout << "Ошибка: "s << e.what() << endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment