Created
November 16, 2017 15:17
-
-
Save e5l/95f0abbaeecc5f6b7c5cf066414e26c2 to your computer and use it in GitHub Desktop.
Rational
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <iostream> | |
#include <cstdlib> | |
class rational; | |
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); | |
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); | |
class rational | |
{ | |
public: | |
/* минимально необходимый набор методов */ | |
rational(int number) | |
: rational(number, 1) | |
{} | |
rational(int nominator, unsigned int denominator) | |
: _nominator(nominator) | |
, _denominator(denominator) | |
{ | |
simplify(); | |
} | |
/* прибавить текущее к переданному */ | |
rational &add(const rational &other) | |
{ | |
_nominator = _nominator * other.denominator() + _denominator * other._nominator; | |
_denominator *= other._denominator; | |
simplify(); | |
return *this; | |
} | |
rational &operator+=(const rational &other) | |
{ | |
return add(other); | |
} | |
rational &operator-=(const rational &other) | |
{ | |
return add(rational(other).negate()); | |
} | |
/* умножить текущее на переданное */ | |
rational &multiply(const rational &other) | |
{ | |
_nominator *= other._nominator; | |
_denominator *= other._denominator; | |
simplify(); | |
return *this; | |
} | |
rational &operator*=(const rational &other) | |
{ | |
return multiply(other); | |
} | |
rational &operator/=(const rational &other) | |
{ | |
return multiply(1 / other); | |
} | |
/* изменить знак числа */ | |
rational &negate() | |
{ | |
_nominator *= -1; | |
simplify(); | |
return *this; | |
} | |
/* проверить равны ли два числа */ | |
bool equals(const rational &other) const | |
{ | |
return _nominator == other._nominator && _denominator == other._denominator; | |
} | |
/* проверить правда ли что текущее число меньше переданного */ | |
bool less(const rational &other) const | |
{ | |
rational left = *this; | |
rational right = other; | |
return left.add(right.negate()).negative(); | |
} | |
/* проверить отрицательность числа */ | |
bool negative() const | |
{ | |
return _nominator < 0; | |
} | |
/* числитель */ | |
unsigned int nominator() const | |
{ | |
return negative() ? -_nominator : _nominator; | |
} | |
/* знаменатель */ | |
unsigned int denominator() const | |
{ | |
return _denominator; | |
} | |
/* выделить целую часть(округлить в сторону нуля) */ | |
int toInt() const | |
{ | |
return std::div(_nominator, _denominator).quot; | |
} | |
rational operator-() | |
{ | |
return rational(*this).negate(); | |
} | |
rational &operator++() | |
{ | |
add(1); | |
return *this; | |
} | |
rational operator++(int) | |
{ | |
rational result(*this); | |
add(1); | |
return result; | |
} | |
rational &operator--() | |
{ | |
add(-1); | |
return *this; | |
} | |
rational operator--(int) | |
{ | |
rational result(*this); | |
add(-1); | |
return result; | |
} | |
explicit operator int() | |
{ | |
return toInt(); | |
} | |
private: | |
int _nominator; | |
unsigned int _denominator; | |
void simplify() | |
{ | |
unsigned int nominator = (_nominator < 0) ? -_nominator : _nominator; | |
int divisor = gcd(nominator, _denominator); | |
_nominator /= divisor; | |
_denominator /= divisor; | |
if (_nominator == 0) _denominator = 1; | |
} | |
int gcd(int a, int b) | |
{ | |
if (b == 0) return a; | |
return gcd(b, a % b); | |
} | |
}; | |
inline bool operator==(const rational &lhs, const rational &rhs) | |
{ | |
return lhs.equals(rhs); | |
} | |
inline bool operator!=(const rational &lhs, const rational &rhs) | |
{ | |
return !lhs.equals(rhs); | |
} | |
inline bool operator<(const rational &lhs, const rational &rhs) | |
{ | |
return lhs.less(rhs); | |
} | |
inline bool operator<=(const rational &lhs, const rational &rhs) | |
{ | |
return lhs < rhs || lhs == rhs; | |
} | |
inline bool operator>=(const rational &lhs, const rational &rhs) | |
{ | |
return !lhs.less(rhs); | |
} | |
inline bool operator>(const rational &lhs, const rational &rhs) | |
{ | |
return lhs >= rhs && lhs != rhs; | |
} | |
inline rational operator+(const rational &lhs, const rational &rhs) | |
{ | |
return rational(lhs).add(rhs); | |
} | |
inline rational operator-(const rational &lhs, const rational &rhs) | |
{ | |
return rational(lhs).add(rational(rhs).negate()); | |
} | |
inline rational operator*(const rational &lhs, const rational &rhs) | |
{ | |
return rational(lhs).multiply(rhs); | |
} | |
inline rational operator/(const rational &lhs, const rational &rhs) | |
{ | |
int nominator = rhs.denominator() * (rhs.negative() ? -1 : 1); | |
unsigned int denominator = rhs.nominator() * (rhs.negative() ? -1 : 1); | |
return rational(lhs).multiply(rational(nominator, denominator)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment