#pragma once #include #include #include #include class Rational { public: // Конструктор по умолчанию: 0/1 Rational() = default; // Конструктор числителя Rational(int numerator) : numerator_{ numerator }, denominator_{ 1 } { Reduction(); } // Конструктор из числителя и знаменателя Rational(int numerator, int denominator) : numerator_{ numerator }, denominator_{ denominator } { Reduction(); } // Копирующий конструктор Rational(const Rational& other) : numerator_{other.numerator_}, denominator_(other.denominator_) { } // Возвращает обратную дробь Rational Inv() const { return Rational(denominator_, numerator_); } // Получить числитель int GetNumerator() const { return numerator_; } // Получить знаменатель int GetDenominator() const { return denominator_; } // Перегрузка оператора присваивания Rational& operator=(const Rational&) = default; // Унарный плюс Rational operator+() const { return *this; return {numerator_, denominator_}; } // Унарный минус Rational operator-() const { return Rational(-numerator_, denominator_); } // Сложение с присваиванием Rational& operator+=(const Rational& other) { numerator_ = numerator_ * other.denominator_ + other.numerator_ * denominator_; denominator_ = denominator_ * other.denominator_; Reduction(); return *this; } // Вычитание с присваиванием Rational& operator-=(const Rational& other) { numerator_ = numerator_ * other.denominator_ - other.numerator_ * denominator_; denominator_ = denominator_ * other.denominator_; Reduction(); return *this; } // Умножение с присваиванием Rational& operator*=(const Rational& other) { numerator_ = numerator_ * other.numerator_; denominator_ = denominator_ * other.denominator_; Reduction(); return *this; } // Деление с присваиванием Rational& operator/=(const Rational& other) { numerator_ *= other.denominator_; denominator_ *= other.numerator_; Reduction(); return *this; } // Сложение Rational operator+(const Rational& other) const { Rational result(*this); result += other; return result; } // Вычитание Rational operator-(const Rational& other) const { Rational result(*this); result -= other; return result; } // Умножение Rational operator*(const Rational& other) const { Rational result(*this); result *= other; return result; } // Деление Rational operator/(const Rational& other) const { Rational result(*this); result /= other; return result; } // Проверка равенства дробей bool operator==(const Rational& other) const { return static_cast(numerator_) * other.denominator_ == static_cast(other.numerator_) * denominator_; } // Трехстороннее сравнение auto operator<=>(const Rational& other) const { return static_cast(numerator_) * other.denominator_ <=> static_cast(other.numerator_) * denominator_; } // Вывод дроби в поток friend std::ostream& operator<<(std::ostream& os, const Rational& r) { if (r.denominator_ == 1) { os << r.numerator_; } else { os << r.numerator_ << " / " << r.denominator_; } return os; } // Чтение дроби из потока friend std::istream& operator>>(std::istream& is, Rational& r) { int n; int d; char div; is >> n; if (!(is >> std::ws >> div)) { r = Rational(n, 1); return is; } if (div != '/') { is.unget(); r = Rational(n, 1); return is; } is >> d; if (!is || d == 0) { is.setstate(std::ios::failbit); r = Rational(n, 1); } else { r = Rational(n, d); } return is; } private: int numerator_ = 0; int denominator_ = 1; // Нормализация дроби void Reduction() { if (numerator_ == 0) { denominator_ = 1; return; } if (denominator_ < 0) { numerator_ = -numerator_; denominator_ = -denominator_; } const int divisor = std::gcd(numerator_, denominator_); numerator_ /= divisor; denominator_ /= divisor; } };