/** * Класс для работы с дробями * С перегруженными операторами + - * / */ // Файл Fraction.hpp #pragma once #include #include #include using std::string; using std::ostream; // Наибольший общий делитель // (англ.) greatest common divisor int get_gcd(int a, int b); // Наименьшее общее кратное // (англ.) least common multiple int get_lcm(int a, int b); class Fraction { private: // Числитель int _numerator; // Знаменатель int _denominator; // Функция нужна для сокращения дроби void reduce(); public: // Конструктор принимает значения числителя и знаменателя Fraction(int numerator, int denominator); // Возвращаем дробь в виде строки string toString() const; // Геттеры int getNumerator() const; int getDenominator() const; // Перегружаем операторы основных операций Fraction operator+(const Fraction &fraction) const; Fraction operator-(const Fraction &fraction) const; Fraction operator*(const Fraction &fraction) const; Fraction operator/(const Fraction &fraction) const; }; // Перегружаем оператор вывода ostream& operator << (ostream& ofstream, const Fraction &fraction); // Файл Fraction.cpp #pragma once #include "Fraction.hpp" int get_gcd(int a, int b) { while (b > 0) { int c = a % b; a = b; b = c; } return a; } int get_lcm(int a, int b) { return get_gcd(a, b) * a * b; } Fraction::Fraction(int numerator = 1, int denominator = 1) : _numerator(numerator), _denominator(denominator) { // Выбрасываем исключение, если знаменатель равен нулю assert(denominator != 0 && "Error: denominator can't be 0"); } void Fraction::reduce() { // Находим НОД int gcd = get_gcd(abs(_numerator), _denominator); if (gcd != 1) { _numerator = _numerator / gcd; _denominator = _denominator / gcd; } } string Fraction::toString() const { string fraction = std::to_string(_numerator); if (_denominator != 1) { fraction.append("/"); fraction.append(std::to_string(_denominator)); } return fraction; } Fraction Fraction::operator*(const Fraction &fraction) const { // Получаем числитель и знаменатель новой дроби int numerator = _numerator * fraction.getNumerator(); int denominator = _denominator * fraction.getDenominator(); // Создаем новый класс дроби Fraction newFraction(numerator, denominator); newFraction.reduce(); return newFraction; } Fraction Fraction::operator/(const Fraction &fraction) const { // Получаем числитель и знаменатель новой дроби int numerator = _numerator * fraction.getDenominator(); int denominator = _denominator * fraction.getNumerator(); // Создаем новый класс дроби Fraction newFraction(numerator, denominator); newFraction.reduce(); return newFraction; } // Ищем НОК для знаменателей. Умножаем оба числителя на него Fraction Fraction::operator-(const Fraction &fraction) const { int numerator = _numerator * fraction.getDenominator() - fraction.getNumerator() * _denominator; int denominator = get_lcm(_denominator, fraction.getDenominator()); // Создаем новый класс дроби Fraction newFraction(numerator, denominator); newFraction.reduce(); return newFraction; } Fraction Fraction::operator+(const Fraction &fraction) const { int numerator = _numerator * fraction.getDenominator() + fraction.getNumerator() * _denominator; int denominator = get_lcm(_denominator, fraction.getDenominator()); // Создаем новый класс дроби Fraction newFraction(numerator, denominator); newFraction.reduce(); return newFraction; } int Fraction::getNumerator() const { return _numerator; } int Fraction::getDenominator() const { return _denominator; } ostream& operator << (ostream& ofstream, const Fraction &fraction) { ofstream << fraction.toString(); return ofstream; } /** * Пример использования: * int main() { * Fraction first(-5, 3); * Fraction second(4, 10); * * Fraction result = first / second; * cout << result << endl; * return 0; * } */