Какие случаи я не разобрал?
```
//rational.cpp
#include "rational.h"
#include <string>
#include <cstdlib>

const int DIGITS = 10;

void Rational::Set(int64_t numer, int64_t denom) {
    if (denom == 0) {
        throw RationalDivisionByZero{};
    }

    int64_t del = std::gcd(std::abs(numer), std::abs(denom));

    numer_ = static_cast<int>(numer / del);
    denom_ = static_cast<int>(denom / del);

    if (denom_ < 0) {
        numer_ *= -1;
        denom_ *= -1;
    }
}

Rational::Rational() {
    numer_ = 0;
    denom_ = 1;
}

Rational::Rational(int value) : numer_(value) {  // NOLINT
    denom_ = 1;
}

Rational::Rational(int numer, int denom) {
    numer_ = numer;
    denom_ = denom;

    Set(numer_, denom_);
}

int Rational::GetNumerator() const {
    return numer_;
}

int Rational::GetDenominator() const {
    return denom_;
}

void Rational::SetNumerator(int value) {
    numer_ = value;

    Set(numer_, denom_);
}

void Rational::SetDenominator(int value) {
    if (value == 0) {
        throw RationalDivisionByZero{};
    }

    denom_ = value;

    Set(numer_, denom_);
}

int64_t Mul(int a, int b) {
    return static_cast<int64_t>(a) * static_cast<int64_t>(b);
}

void Rational::Normalize(int64_t numer, int64_t denom) {
    Set(numer, denom);
}

Rational& operator+=(Rational& lhs, const Rational& rhs) {
    int64_t new_numer = Mul(lhs.GetNumerator(), rhs.GetDenominator()) + Mul(lhs.GetDenominator(), rhs.GetNumerator());
    int64_t new_denom = Mul(lhs.GetDenominator(), rhs.GetDenominator());

    lhs.Normalize(new_numer, new_denom);

    return lhs;
}

Rational& operator*=(Rational& lhs, const Rational& rhs) {
    int64_t new_numer = Mul(lhs.GetNumerator(), rhs.GetNumerator());
    int64_t new_denom = Mul(lhs.GetDenominator(), rhs.GetDenominator());

    lhs.Normalize(new_numer, new_denom);

    return lhs;
}

Rational& operator++(Rational& ratio) {
    ratio.Normalize(static_cast<int64_t>(ratio.GetNumerator()) + ratio.GetDenominator(), ratio.GetDenominator());

    return ratio;
}

Rational& operator--(Rational& ratio) {
    ratio.Normalize(static_cast<int64_t>(ratio.GetNumerator()) - ratio.GetDenominator(), ratio.GetDenominator());

    return ratio;
}

std::istream& operator>>(std::istream& is, Rational& ratio) {
    std::string s;
    int64_t numer = 0;
    int64_t denom = 0;
    char slash = '/';

    is >> s;

    bool is_negative = (s[0] == '-');
    bool is_denom = false;

    if (is_negative) {
        s.erase(0, 1);
    }

    for (size_t i = 0; i < s.size(); ++i) {
        if (s[i] == slash) {
            is_denom = true;
        } else {
            if (!is_denom) {
                numer = numer * DIGITS + (s[i] - '0');
            } else {
                denom = denom * DIGITS + (s[i] - '0');
            }
        }
    }

    if (is_negative) {
        numer *= -1;
    }

    if (!is_denom) {
        denom = 1;
    }

    ratio.Normalize(numer, denom);

    return is;
}

Rational operator+(const Rational& ratio) {
    return ratio;
}

Rational operator-(const Rational& ratio) {
    return Rational(-ratio.GetNumerator(), ratio.GetDenominator());
}

Rational& operator-=(Rational& lhs, const Rational& rhs) {
    int64_t new_numer = Mul(lhs.GetNumerator(), rhs.GetDenominator()) - Mul(lhs.GetDenominator(), rhs.GetNumerator());
    int64_t new_denom = Mul(lhs.GetDenominator(), rhs.GetDenominator());

    lhs.Normalize(new_numer, new_denom);

    return lhs;
}

Rational& operator/=(Rational& lhs, const Rational& rhs) {
    if (rhs.GetNumerator() == 0) {
        throw RationalDivisionByZero{};
    }

    int64_t new_numer = Mul(lhs.GetNumerator(), rhs.GetDenominator());
    int64_t new_denom = Mul(lhs.GetDenominator(), rhs.GetNumerator());

    lhs.Normalize(new_numer, new_denom);

    return lhs;
}

Rational operator+(const Rational& lhs, const Rational& rhs) {
    int64_t new_numer = Mul(lhs.GetNumerator(), rhs.GetDenominator()) + Mul(lhs.GetDenominator(), rhs.GetNumerator());
    int64_t new_denom = Mul(lhs.GetDenominator(), rhs.GetDenominator());

    Rational ans;
    ans.Normalize(new_numer, new_denom);

    return ans;
}

Rational operator-(const Rational& lhs, const Rational& rhs) {
    int64_t new_numer = Mul(lhs.GetNumerator(), rhs.GetDenominator()) - Mul(lhs.GetDenominator(), rhs.GetNumerator());
    int64_t new_denom = Mul(lhs.GetDenominator(), rhs.GetDenominator());

    Rational ans;
    ans.Normalize(new_numer, new_denom);

    return ans;
}

Rational operator*(const Rational& lhs, const Rational& rhs) {
    int64_t new_numer = Mul(lhs.GetNumerator(), rhs.GetNumerator());
    int64_t new_denom = Mul(lhs.GetDenominator(), rhs.GetDenominator());

    Rational ans;
    ans.Normalize(new_numer, new_denom);

    return ans;
}

Rational operator/(const Rational& lhs, const Rational& rhs) {
    if (rhs.GetNumerator() == 0) {
        throw RationalDivisionByZero{};
    }

    int64_t new_numer = Mul(lhs.GetNumerator(), rhs.GetDenominator());
    int64_t new_denom = Mul(lhs.GetDenominator(), rhs.GetNumerator());

    Rational ans;
    ans.Normalize(new_numer, new_denom);

    return ans;
}

Rational operator++(Rational& ratio, int) {
    Rational temp = ratio;
    ++ratio;
    return temp;
}

Rational operator--(Rational& ratio, int) {
    Rational temp = ratio;
    --ratio;
    return temp;
}

bool operator<(const Rational& lhs, const Rational& rhs) {
    return Mul(lhs.GetNumerator(), rhs.GetDenominator()) < Mul(lhs.GetDenominator(), rhs.GetNumerator());
}

bool operator>(const Rational& lhs, const Rational& rhs) {
    return Mul(lhs.GetNumerator(), rhs.GetDenominator()) > Mul(lhs.GetDenominator(), rhs.GetNumerator());
}

bool operator<=(const Rational& lhs, const Rational& rhs) {
    return Mul(lhs.GetNumerator(), rhs.GetDenominator()) <= Mul(lhs.GetDenominator(), rhs.GetNumerator());
}

bool operator>=(const Rational& lhs, const Rational& rhs) {
    return Mul(lhs.GetNumerator(), rhs.GetDenominator()) >= Mul(lhs.GetDenominator(), rhs.GetNumerator());
}

bool operator==(const Rational& lhs, const Rational& rhs) {
    return Mul(lhs.GetNumerator(), rhs.GetDenominator()) == Mul(lhs.GetDenominator(), rhs.GetNumerator());
}

bool operator!=(const Rational& lhs, const Rational& rhs) {
    return Mul(lhs.GetNumerator(), rhs.GetDenominator()) != Mul(lhs.GetDenominator(), rhs.GetNumerator());
}

std::ostream& operator<<(std::ostream& os, const Rational& ratio) {
    if (ratio.GetDenominator() == 1) {
        os << ratio.GetNumerator();
    } else {
        os << ratio.GetNumerator() << '/' << ratio.GetDenominator();
    }

    return os;
}
```

```
//rational.h
#pragma once

#include <stdexcept>
#include <iostream>
#include <numeric>

class RationalDivisionByZero : public std::runtime_error {
public:
    RationalDivisionByZero() : std::runtime_error("RationalDivisionByZero") {
    }
};

class Rational {
public:
    Rational();

    Rational(int value);  // NOLINT

    Rational(int numer, int denom);

    int GetNumerator() const;

    int GetDenominator() const;

    void SetNumerator(int value);

    void SetDenominator(int value);

    void Normalize(int64_t numer, int64_t denom);

    friend Rational& operator+=(Rational& lhs, const Rational& rhs);

    friend Rational& operator*=(Rational& lhs, const Rational& rhs);

    friend Rational& operator++(Rational& ratio);  // faster than += 1

    friend Rational& operator--(Rational& ratio);

    friend std::istream& operator>>(std::istream& is, Rational& ratio);

private:
    void Set(int64_t numer, int64_t denom);

    int numer_;
    int denom_;
};

Rational operator+(const Rational& ratio);

Rational operator-(const Rational& ratio);

Rational& operator-=(Rational& lhs, const Rational& rhs);

Rational& operator/=(Rational& lhs, const Rational& rhs);

Rational operator+(const Rational& lhs, const Rational& rhs);

Rational operator-(const Rational& lhs, const Rational& rhs);

Rational operator*(const Rational& lhs, const Rational& rhs);

Rational operator/(const Rational& lhs, const Rational& rhs);

Rational operator++(Rational& ratio, int);

Rational operator--(Rational& ratio, int);

bool operator<(const Rational& lhs, const Rational& rhs);

bool operator>(const Rational& lhs, const Rational& rhs);

bool operator<=(const Rational& lhs, const Rational& rhs);

bool operator>=(const Rational& lhs, const Rational& rhs);

bool operator==(const Rational& lhs, const Rational& rhs);

bool operator!=(const Rational& lhs, const Rational& rhs);

std::ostream& operator<<(std::ostream& os, const Rational& ratio);
```