2021-06-24 13:43:37 +00:00
|
|
|
|
#ifndef EXERCISE_3_HPP_
|
|
|
|
|
#define EXERCISE_3_HPP_
|
|
|
|
|
|
2021-06-25 20:59:50 +00:00
|
|
|
|
#include <iostream>
|
2021-06-24 13:43:37 +00:00
|
|
|
|
|
2021-06-25 20:59:50 +00:00
|
|
|
|
class Fraction
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
bool is_zero;
|
|
|
|
|
bool is_integer;
|
|
|
|
|
int numerator;
|
|
|
|
|
int denominator;
|
2021-06-24 13:43:37 +00:00
|
|
|
|
|
2021-06-25 20:59:50 +00:00
|
|
|
|
/*
|
|
|
|
|
* Поиск наибольшего общего делителя
|
|
|
|
|
* для числителя и знаменателя
|
|
|
|
|
*/
|
|
|
|
|
int NOD(int n1, int n2)
|
|
|
|
|
{
|
|
|
|
|
int div;
|
|
|
|
|
if (n1 == n2) return n1;
|
|
|
|
|
int d = n1 - n2;
|
|
|
|
|
if (d < 0)
|
|
|
|
|
{
|
|
|
|
|
d = -d;
|
|
|
|
|
div = NOD(n1, d);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
div = NOD(n2, d);
|
2021-06-24 13:43:37 +00:00
|
|
|
|
|
2021-06-25 20:59:50 +00:00
|
|
|
|
return div;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Поиск наименьшего общего кратного
|
|
|
|
|
* для знаменателей
|
|
|
|
|
*/
|
|
|
|
|
int NOK(int n1, int n2)
|
|
|
|
|
{
|
|
|
|
|
return n1 * n2 / NOD(n1, n2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Функция сокращения дроби
|
|
|
|
|
*/
|
|
|
|
|
void reduceFraction(int& a, int& b)
|
|
|
|
|
{
|
|
|
|
|
int divisor = NOD(abs(a), abs(b));
|
|
|
|
|
a = a / divisor;
|
|
|
|
|
b = b / divisor;
|
|
|
|
|
}
|
|
|
|
|
public:
|
|
|
|
|
Fraction () : numerator(0), denominator(0)
|
|
|
|
|
{
|
|
|
|
|
is_zero = true;
|
|
|
|
|
is_integer = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Fraction(int num, int dnum) : numerator(num), denominator(dnum)
|
|
|
|
|
{
|
|
|
|
|
if (numerator == 0 || denominator == 0)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "Числитель или знаменатель не может быть нулевым!\n"
|
|
|
|
|
<< "Число будет инициализировано нулём!" << std::endl;
|
|
|
|
|
numerator = 0;
|
|
|
|
|
denominator = 0;
|
|
|
|
|
is_zero = true;
|
|
|
|
|
is_integer = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
is_zero = false;
|
|
|
|
|
is_integer = (abs(numerator) == abs(denominator) || denominator == 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
friend std::ostream& operator<<(std::ostream&, const Fraction&);
|
|
|
|
|
|
|
|
|
|
Fraction operator+(const Fraction&);
|
|
|
|
|
Fraction operator-(const Fraction&);
|
|
|
|
|
Fraction operator*(const Fraction&);
|
|
|
|
|
Fraction operator/(const Fraction&);
|
|
|
|
|
|
|
|
|
|
Fraction operator-() const;
|
|
|
|
|
|
|
|
|
|
bool operator==(const Fraction&);
|
|
|
|
|
bool operator!=(const Fraction&);
|
|
|
|
|
bool operator<(const Fraction&);
|
|
|
|
|
bool operator>=(const Fraction&);
|
|
|
|
|
bool operator>(const Fraction&);
|
|
|
|
|
bool operator<=(const Fraction&);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::ostream& operator<<(std::ostream& s, const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
if (f.is_integer)
|
|
|
|
|
{
|
|
|
|
|
if (f.is_zero)
|
|
|
|
|
s << f.numerator;
|
|
|
|
|
else
|
|
|
|
|
s << f.numerator / f.denominator;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
s << f.numerator << '/' << f.denominator;
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Fraction Fraction::operator+(const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
if (f.is_zero)
|
|
|
|
|
return Fraction(numerator, denominator);
|
|
|
|
|
|
|
|
|
|
if (is_zero)
|
|
|
|
|
return Fraction(f.numerator, f.denominator);
|
|
|
|
|
|
|
|
|
|
int new_denominator = NOK(denominator, f.denominator);
|
|
|
|
|
int new_numerator = numerator * (new_denominator / denominator) + f.numerator * (new_denominator / f.denominator);
|
|
|
|
|
|
|
|
|
|
reduceFraction(new_numerator, new_denominator);
|
|
|
|
|
|
|
|
|
|
return Fraction(new_numerator, new_denominator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Fraction Fraction::operator-(const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
if (f.is_zero)
|
|
|
|
|
return Fraction(numerator, denominator);
|
|
|
|
|
|
|
|
|
|
if (is_zero)
|
|
|
|
|
return Fraction(-f.numerator, f.denominator);
|
|
|
|
|
|
|
|
|
|
int new_denominator = NOK(denominator, f.denominator);
|
|
|
|
|
int new_numerator = numerator * (new_denominator / denominator) - f.numerator * (new_denominator / f.denominator);
|
|
|
|
|
|
|
|
|
|
if (new_numerator == 0)
|
|
|
|
|
return Fraction();
|
|
|
|
|
|
|
|
|
|
reduceFraction(new_numerator, new_denominator);
|
|
|
|
|
|
|
|
|
|
return Fraction(new_numerator, new_denominator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Fraction Fraction::operator*(const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
if (is_zero || f.is_zero)
|
|
|
|
|
return Fraction();
|
|
|
|
|
|
|
|
|
|
int new_numerator = numerator * f.numerator;
|
|
|
|
|
int new_denominator = denominator * f.denominator;
|
|
|
|
|
|
|
|
|
|
reduceFraction(new_numerator, new_denominator);
|
|
|
|
|
|
|
|
|
|
return Fraction(new_numerator, new_denominator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Fraction Fraction::operator/(const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
if (f.is_zero)
|
|
|
|
|
{
|
|
|
|
|
std::cout << " [На 0 делить нельзя!] ";
|
|
|
|
|
return Fraction();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_zero)
|
|
|
|
|
return Fraction();
|
|
|
|
|
|
|
|
|
|
return *this * Fraction(f.denominator, f.numerator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Fraction Fraction::operator-() const
|
|
|
|
|
{
|
|
|
|
|
return Fraction(-numerator, denominator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Fraction::operator==(const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
if (is_zero || f.is_zero)
|
|
|
|
|
return numerator == f.numerator;
|
|
|
|
|
|
|
|
|
|
int a_n = numerator;
|
|
|
|
|
int a_d = denominator;
|
|
|
|
|
|
|
|
|
|
int b_n = f.numerator;
|
|
|
|
|
int b_d = f.denominator;
|
|
|
|
|
|
|
|
|
|
reduceFraction(a_n, a_d);
|
|
|
|
|
reduceFraction(b_n, b_d);
|
|
|
|
|
|
|
|
|
|
return a_n == b_n && a_d == b_d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Fraction::operator!=(const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
return !(*this == f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Fraction::operator<(const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
if (is_zero || f.is_zero)
|
|
|
|
|
return numerator < f.numerator;
|
|
|
|
|
|
|
|
|
|
int new_denominator = NOK(denominator, f.denominator);
|
|
|
|
|
int a_n = numerator * (new_denominator / denominator);
|
|
|
|
|
int b_n = f.numerator * (new_denominator / f.denominator);
|
|
|
|
|
|
|
|
|
|
return a_n < b_n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Fraction::operator>=(const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
return (*this == f || !(*this < f));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Fraction::operator>(const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
return (*this != f && !(*this < f));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Fraction::operator<=(const Fraction& f)
|
|
|
|
|
{
|
|
|
|
|
return (*this == f || *this < f);
|
|
|
|
|
}
|
2021-06-24 13:43:37 +00:00
|
|
|
|
|
|
|
|
|
#endif
|