Advertisement
Gistrec

Класс для работы с дробями

Jun 6th, 2019
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.86 KB | None | 0 0
  1. /**
  2.  * Класс для работы с дробями
  3.  * С перегруженными операторами + - * /
  4.  */
  5.  
  6. // Файл Fraction.hpp
  7. #pragma once
  8. #include <string>
  9. #include <cassert>
  10. #include <iostream>
  11.  
  12. using std::string;
  13. using std::ostream;
  14.  
  15. // Наибольший общий делитель
  16. // (англ.) greatest common divisor
  17. int get_gcd(int a, int b);
  18.  
  19. // Наименьшее общее кратное
  20. // (англ.) least common multiple
  21. int get_lcm(int a, int b);
  22.  
  23.  
  24. class Fraction {
  25. private:
  26.     // Числитель
  27.     int _numerator;
  28.  
  29.     // Знаменатель
  30.     int _denominator;
  31.  
  32.     // Функция нужна для сокращения дроби
  33.     void reduce();
  34.  
  35. public:
  36.     // Конструктор принимает значения числителя и знаменателя
  37.     Fraction(int numerator, int denominator);
  38.  
  39.     // Возвращаем дробь в виде строки
  40.     string toString() const;
  41.  
  42.     // Геттеры
  43.     int getNumerator() const;
  44.     int getDenominator() const;
  45.  
  46.     // Перегружаем операторы основных операций
  47.     Fraction operator+(const Fraction &fraction) const;
  48.     Fraction operator-(const Fraction &fraction) const;
  49.     Fraction operator*(const Fraction &fraction) const;
  50.     Fraction operator/(const Fraction &fraction) const;
  51. };
  52.  
  53. // Перегружаем оператор вывода
  54. ostream& operator << (ostream& ofstream, const Fraction &fraction);
  55.  
  56.  
  57.  
  58. // Файл Fraction.cpp
  59. #pragma once
  60. #include "Fraction.hpp"
  61.  
  62.  
  63. int get_gcd(int a, int b) {
  64.     while (b > 0) {
  65.         int c = a % b;
  66.         a = b;
  67.         b = c;
  68.     }
  69.     return a;
  70. }
  71.  
  72. int get_lcm(int a, int b) {
  73.     return get_gcd(a, b) * a * b;
  74. }
  75.  
  76.  
  77. Fraction::Fraction(int numerator = 1, int denominator = 1)
  78.     : _numerator(numerator), _denominator(denominator) {
  79.     // Выбрасываем исключение, если знаменатель равен нулю
  80.     assert(denominator != 0 && "Error: denominator can't be 0");
  81. }
  82.  
  83.  
  84. void Fraction::reduce() {
  85.     // Находим НОД
  86.     int gcd = get_gcd(abs(_numerator), _denominator);
  87.     if (gcd != 1) {
  88.         _numerator = _numerator / gcd;
  89.         _denominator = _denominator / gcd;
  90.     }
  91. }
  92.  
  93. string Fraction::toString() const {
  94.     string fraction = std::to_string(_numerator);
  95.     if (_denominator != 1) {
  96.         fraction.append("/");
  97.         fraction.append(std::to_string(_denominator));
  98.     }
  99.     return fraction;
  100. }
  101.  
  102. Fraction Fraction::operator*(const Fraction &fraction) const {
  103.     // Получаем числитель и знаменатель новой дроби
  104.     int numerator   = _numerator   * fraction.getNumerator();
  105.     int denominator = _denominator * fraction.getDenominator();
  106.  
  107.     // Создаем новый класс дроби
  108.     Fraction newFraction(numerator, denominator);
  109.     newFraction.reduce();
  110.     return newFraction;
  111. }
  112.  
  113. Fraction Fraction::operator/(const Fraction &fraction) const {
  114.     // Получаем числитель и знаменатель новой дроби
  115.     int numerator = _numerator * fraction.getDenominator();
  116.     int denominator = _denominator * fraction.getNumerator();
  117.  
  118.     // Создаем новый класс дроби
  119.     Fraction newFraction(numerator, denominator);
  120.     newFraction.reduce();
  121.     return newFraction;
  122. }
  123.  
  124. // Ищем НОК для знаменателей. Умножаем оба числителя на него
  125. Fraction Fraction::operator-(const Fraction &fraction) const {
  126.     int numerator = _numerator * fraction.getDenominator() - fraction.getNumerator() * _denominator;
  127.     int denominator = get_lcm(_denominator, fraction.getDenominator());
  128.  
  129.     // Создаем новый класс дроби
  130.     Fraction newFraction(numerator, denominator);
  131.     newFraction.reduce();
  132.     return newFraction;
  133. }
  134.  
  135. Fraction Fraction::operator+(const Fraction &fraction) const {
  136.     int numerator = _numerator * fraction.getDenominator() + fraction.getNumerator() * _denominator;
  137.     int denominator = get_lcm(_denominator, fraction.getDenominator());
  138.  
  139.     // Создаем новый класс дроби
  140.     Fraction newFraction(numerator, denominator);
  141.     newFraction.reduce();
  142.     return newFraction;
  143. }
  144.  
  145. int Fraction::getNumerator() const {
  146.     return _numerator;
  147. }
  148.  
  149. int Fraction::getDenominator() const {
  150.     return _denominator;
  151. }
  152.  
  153. ostream& operator << (ostream& ofstream, const Fraction &fraction) {
  154.     ofstream << fraction.toString();
  155.     return ofstream;
  156. }
  157.  
  158.  
  159.  
  160. /**
  161.  * Пример использования:
  162.  * int main() {
  163.  *     Fraction first(-5, 3);
  164.  *     Fraction second(4, 10);
  165.  *    
  166.  *     Fraction result = first / second;
  167.  *     cout << result << endl;
  168.  *     return 0;
  169.  * }
  170.  */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement