Upload to git
This commit is contained in:
+194
@@ -0,0 +1,194 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <ostream>
|
||||
|
||||
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<std::int64_t>(numerator_) * other.denominator_ ==
|
||||
static_cast<std::int64_t>(other.numerator_) * denominator_;
|
||||
}
|
||||
|
||||
// Трехстороннее сравнение
|
||||
auto operator<=>(const Rational& other) const {
|
||||
return static_cast<std::int64_t>(numerator_) * other.denominator_ <=>
|
||||
static_cast<std::int64_t>(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;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user