/**
* Класс для работы с дробями
* С перегруженными операторами + - * /
*/
// Файл Fraction.hpp
#pragma once
#include <string>
#include <cassert>
#include <iostream>
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;
* }
*/
Comments
0 B
|👍
/👎