C++ C++;分数类

C++ C++;分数类,c++,C++,我必须创建一个名为分数的类,它有两个私有字段分子、分母。以及一个公共构造函数,默认情况下将分子和分母设置为1。我在我的分数类中包含了4个成员函数:和、差、积、除 那我就不知道下一步该怎么办了。为什么这本书显示分数相等?这跟我有什么关系?我想一个非常重要的问题是我的成员函数应该采用什么参数 另外,禁止分母为0的好方法是什么?抛出异常或强制它等于1 这是问题#5和#6(未显示)的完整源代码,在与问题斗争了几天之后。问题#6只要求实现最大公约数函数,以简化形式返回分数。所以它在这里 如果您认为有办法

我必须创建一个名为分数的类,它有两个私有字段分子、分母。以及一个公共构造函数,默认情况下将分子和分母设置为1。我在我的分数类中包含了4个成员函数:和、差、积、除

那我就不知道下一步该怎么办了。为什么这本书显示分数相等?这跟我有什么关系?我想一个非常重要的问题是我的成员函数应该采用什么参数

另外,禁止分母为0的好方法是什么?抛出异常或强制它等于1

这是问题#5和#6(未显示)的完整源代码,在与问题斗争了几天之后。问题#6只要求实现最大公约数函数,以简化形式返回分数。所以它在这里

如果您认为有办法优化此代码,我很乐意听到您的回答

#include <iostream>
using namespace std;

class Fraction
{
private:
    int numerator, denominator; 
public:
    Fraction()
    {
        numerator = 1;
        denominator = 1;
    }
    Fraction(int n, int d)
    {
        numerator = n;
        if (d==0) 
        {
            cout << "ERROR: ATTEMPTING TO DIVIDE BY ZERO" << endl;
            exit(0); // will terminate the program if division by 0 is attempted
        }
        else
            denominator = d;
    }
    /*In the following functions I am dividing both numerator and denominator by the gcd function.
    GCD function accepts both numerator and denominator values. If we had 2 fractions, 1/2 and 1/4
    and we passed it into the Sum, the result would be n=6 and d=8. These are the values that GCD
    function will accept, find greatest common divisor and return the integer value of 2. In my case 
    am diving both numerator and denominator on the same line by the greatest common divisor. Although 
    it probably would be more efficient to create a local int variable and store GCD value in it, but
    for such small program it shouldn't make any difference.*/
    Fraction Sum(Fraction otherFraction)
    {
        int n = numerator*otherFraction.denominator+otherFraction.numerator*denominator;
        int d = denominator*otherFraction.denominator;
        return Fraction(n/gcd(n,d),d/gcd(n,d));
    }
    Fraction Difference(Fraction otherFraction)
    {
        int n = numerator*otherFraction.denominator-otherFraction.numerator*denominator;
        int d = denominator*otherFraction.denominator;
        return Fraction(n/gcd(n,d),d/gcd(n,d));
    }
    Fraction Product(Fraction otherFraction)
    {
        int n = numerator*otherFraction.numerator;
        int d = denominator*otherFraction.denominator;
        return Fraction(n/gcd(n,d),d/gcd(n,d));
    }
    Fraction Division(Fraction otherFraction)
    {
        int n = numerator*otherFraction.denominator;
        int d = denominator*otherFraction.numerator;
        return Fraction(n/gcd(n,d),d/gcd(n,d));
    }
    // I got the GCD algorithm from the following source:
    // Source C#: http://www.ww.functionx.com/csharp2/examples/gcd.htm
    int gcd(int n, int d)
    {
        int remainder;
        while (d != 0)
        {
            remainder = n % d;
            n = d;
            d = remainder;
        }
        return n;
    }
    void show() // Display method
    {
        if (denominator == 1) // e.g. fraction 2/1 will display simply as 2
            cout << numerator << endl;
        else
            cout << numerator << "/" << denominator << endl;
    }
};

int main()
{
    Fraction a(1,2);
    Fraction b(1,4);
    Fraction c;

    c = a.Sum(b); // Result: 3/4
    c.show();

    c = a.Difference(b); // Result: 1/4
    c.show();

    c = a.Product(b); // Result: 1/8
    c.show();

    c = a.Division(b); // Result: 2
    c.show();

    return 0;
}
#包括
使用名称空间std;
类分数
{
私人:
整数分子、分母;
公众:
分数()
{
分子=1;
分母=1;
}
分数(整数n,整数d)
{
分子=n;
如果(d==0)
{
库特
还有什么方法可以禁止0的分母?抛出异常或强制它等于1

这完全是一个风格问题,没有可证明的正确答案

但是…我会有一个例外。再一次,这只是一种风格。无声地更改值将是在完成了调用方要求之外的其他操作后,无声地继续进行

另一种选择是允许0分母,但有一种方法可以通知用户当前的总体值a/b是NaN或无穷大,或者任何您想要定义的“特殊值”


无论如何,请仔细记录它,这样类的用户就可以做出明智的选择。

分数构造函数应该将分子和分母作为参数(或整数)。使用运算符重载可以轻松解决整个问题


是的,当你除以两个分数,分母的分子为零时,别忘了抛出同样的
除法x0
异常。

你可能只想从第一部分开始,用两个构造函数创建一个类,一个如果它们给出两个数,另一个默认为
1

然后,写四个函数,赋值足够好,可以给你方程

如果分母等于零,那么我会抛出一个异常,因为这是用户可以修复的。如果您可以显示导致它为零的原因,例如,如果他们除以(1/2)/(0/4),那么分母为零,这应该是一个错误条件

您需要考虑的一个问题是,这是否是不可变的,因此,如果我有(1/2)和(2/3)我做了一个运算,它应该返回一个新的数字,而不是修改我传入的两个数字中的任何一个。在这种情况下,您的检查总是在构造函数中的零,但您应该解释导致此错误的操作。

您的方法可能是(假设您的类名为“分数”):

(使用您描述的方法名称-我可能会选择其他名称)

每一个都将返回一个包含结果的新
分数
对象


如果使用运算符重载并重新定义
+-/*
的含义,您将获得额外的分数。

一个问题中有这么多问题!让我为您回答一(两)个问题:

为什么这本书显示分数 等价物?我该怎么办 用那个

考虑一下你的
分数
类的这种用法:

TEST(FractionsAreEquivalent)
{
    const Fraction one_over_two(1, 2); // 0.5
    const Fraction two_over_four(2, 4); // 0.5

    const bool equivalent = (one_over_two == two_over_four);

    CHECK(equivalent);
}

这使用了
bool Fraction::operator==(const-Fraction&rhs)const
我是一个新人,如果我的代码看起来很糟糕,我很抱歉

    #include<iostream>
    using namespace std;

    class Fraction
    {
    private :
    int x;//NUMERATOR
    int y;//DENOMINATOR
    public :    
    Fraction(int tx = 0, int ty = 1)
    {
    if(ty == 0)
    { 
    x = 0; 
    y = 1;
    exit(0);                        
    }else
    {
    x = tx;
    y = ty;
    }
    }
    void simplify()
    {
    for(int i = x; i >1;i--)
    {
    if(x%i == 0 && y%i == 0)
    {   
    x = x/i;
    y = y/i;
    } 
    }
    }
    void Input()
    {
    cout<<"Input NUMERATOR: ";
    cin>>x;
    cout<<"Input DENOMINATOR: ";
    cin>>y; 
    if(y==0)
    {
    cout<<"ERROR";
    exit(0);    
    }   
    }
    void Display()
    {
    cout<< x << "/" << y <<endl;
    }
    Fraction operator + (Fraction f){
    Fraction temp;
    temp.x = x * f.y + y * f.x;
    temp.y = y * f.y;
    return temp; 
    }
    Fraction operator - (Fraction f){
    Fraction temp;
    temp.x = x * f.y - y * f.x;
    temp.y = y * f.y;
    return temp; 
    }
    Fraction operator * (Fraction f){
    Fraction temp;
    temp.x = x * f.x ;
    temp.y = y * f.y;
    return temp; 
    }
    Fraction operator / (Fraction f){
    Fraction temp;
    temp.x = x * f.y ;
    temp.y = y * f.x;
    return temp; 
    }
    };
    int main ()
    {   
   
    Fraction f1;
    f1.Input();
    cout<<"Fraction: ";
    f1.simplify();
    f1.Display();
    Fraction f2;    
    f2.Input();
    cout<<"Fraction: ";
    f2.simplify();
    f2.Display();
    Fraction f3,f4,f5,f6;
    f3 = f1 + f2;
    f4 = f1 - f2;
    f5 = f1 * f2;   
    f6 = f1 / f2;
    cout<<"Sum"<<endl;
    f3.simplify();
    f3.Display();
    cout<<"Difference"<<endl;
    f4.simplify();
    f4.Display();
    cout<<"Product"<<endl;
    f5.simplify();
    f5.Display();
    cout<<"Division"<<endl;
    f6.simplify();
    f6.Display();           
    return 0;
    }
#包括
使用名称空间std;
类分数
{
私人:
int x;//分子
int y;//分母
公众:
分数(整数tx=0,整数ty=1)
{
如果(ty==0)
{ 
x=0;
y=1;
出口(0);
}否则
{
x=tx;
y=ty;
}
}
void简化()
{
对于(int i=x;i>1;i--)
{
如果(x%i==0&&y%i==0)
{   
x=x/i;
y=y/i;
} 
}
}
无效输入()
{
coutx;
库蒂;
如果(y==0)
{

cout我创建了这个分数类的一个版本,虽然我的编码很糟糕,但它应该可以工作。请注意,我定义了
操作符,它是在C++20中引入的,并自动定义了
,=
。如果你没有,你可以使用
std::rel_ops
或只是逐个定义它们

分数h:

#include <memory>
#include <numeric>
#include <string>

class Fraction
{
private: 
    long long num{ 1 };
    long long denom{ 1 };

    inline void simplify() {
        auto gcd{ std::make_unique<long long>(std::gcd(num, denom)) };
        num /= *gcd;
        denom /= *gcd;
        gcd.reset();
        if (denom < 0) {
            num = -num;
            denom = -denom;
        }
    }

public:
    Fraction(double numerator = 1, double denominator = 1);
    Fraction(double numerator, double denominator, int integer_part);
    Fraction(const Fraction& f);

    long long numerator() const;
    long long denominator() const;
    auto setnumerator(long long nv);
    auto setdenominator(long long nv);

    double value() const;

    Fraction reciprocal() const;

    std::string str(size_t mode = 0) const;

    bool operator==(const Fraction& f) const;
    auto operator<=>(const Fraction& f) const;
    bool operator==(size_t s) const;
    auto operator<=>(size_t s) const;
    friend bool operator== (size_t s, Fraction& f);
    friend auto operator<=> (size_t s, Fraction& f);
    bool operator==(double d) const;
    auto operator<=>(double d) const;
    friend bool operator== (double d, Fraction& f);
    friend auto operator<=> (double d, Fraction& f);

    Fraction operator+(const Fraction& f) const;
    Fraction operator+(size_t s) const;
    Fraction operator+(double d) const;
    friend Fraction operator+(size_t s, const Fraction& f);
    friend Fraction operator+(double d, const Fraction& f);

    Fraction operator-(const Fraction& f) const;
    Fraction operator-(size_t s) const;
    Fraction operator-(double d) const;
    friend Fraction operator-(size_t s, const Fraction& f);
    friend Fraction operator-(double d, const Fraction& f);

    Fraction operator*(const Fraction& f) const;
    Fraction operator*(size_t s) const;
    Fraction operator*(double d) const;
    friend Fraction operator*(size_t s, const Fraction& f);
    friend Fraction operator*(double d, const Fraction& f);

    Fraction operator/(const Fraction& f) const;
    Fraction operator/(size_t s) const;
    Fraction operator/(double d) const;
    friend Fraction operator/(size_t s, const Fraction& f);
    friend Fraction operator/(double d, const Fraction& f);

    Fraction operator%(const Fraction& f) const;
    Fraction operator%(size_t s) const;
    Fraction operator%(double d) const;
    friend size_t operator%(size_t s, const Fraction& f);
    friend double operator%(double d, const Fraction& f);

    Fraction& operator+=(const Fraction& f);
    Fraction& operator+=(size_t s);
    Fraction& operator+=(double d);
    friend size_t operator+=(size_t s, Fraction& f);
    friend double operator+=(double d, Fraction& f);

    Fraction& operator-=(const Fraction& f);
    Fraction& operator-=(size_t s);
    Fraction& operator-=(double d);
    friend size_t operator-=(size_t s, Fraction& f);
    friend double operator-=(double d, Fraction& f);

    Fraction& operator*=(const Fraction& f);
    Fraction& operator*=(size_t s);
    Fraction& operator*=(double d);
    friend size_t operator*=(size_t s, Fraction& f);
    friend double operator*=(double d, Fraction& f);

    Fraction& operator/=(const Fraction& f);
    Fraction& operator/=(size_t s);
    Fraction& operator/=(double d);
    friend size_t operator/=(size_t s, Fraction& f);
    friend double operator/=(double d, Fraction& f);

    Fraction& operator%=(const Fraction& f);
    Fraction& operator%=(size_t s);
    Fraction& operator%=(double d);
    friend size_t operator%=(size_t s, Fraction& f);
    friend double operator%=(double d, Fraction& f);

    Fraction& operator++();
    Fraction operator++(int);
    Fraction& operator--();
    Fraction operator--(int);

    Fraction operator+();
    Fraction operator-();
    long long operator[](int i);
};

#包括
#包括
#包括
类分数
{
私人:
长数{1};
long-long-denom{1};
内联void simplify(){
自动gcd{std::make_unique(std::gcd(num,denom))};
num/=*gcd;
denom/=*gcd;
gcd.reset();
如果(denom<0){
num=-num;
denom=-denom;
}
}
公众:
分数(双分子=1,双分母=1);
分数(双分子、双分母、整数部分);
分数(常数分数&f);
长分子()常数;
长分母()常数;
自动设置分子(长nv);
自动设置分母(长nv);
双值()常量;
分数倒数()常数;
std::string str(size\u t mode=0)const;
布尔运算符==(常数分数&f)常数;
自动运算符(常数分数和f)常数;
布尔运算符==(大小)常量;
自动操作员(尺寸)常数;
friend bool运算符==(大小、分数和f);
friend自动操作员(大小、分数和f);
布尔运算符==(双d)常量;
自动操作员(双d)常数;
朋友布尔运算符
#include <memory>
#include <numeric>
#include <string>

class Fraction
{
private: 
    long long num{ 1 };
    long long denom{ 1 };

    inline void simplify() {
        auto gcd{ std::make_unique<long long>(std::gcd(num, denom)) };
        num /= *gcd;
        denom /= *gcd;
        gcd.reset();
        if (denom < 0) {
            num = -num;
            denom = -denom;
        }
    }

public:
    Fraction(double numerator = 1, double denominator = 1);
    Fraction(double numerator, double denominator, int integer_part);
    Fraction(const Fraction& f);

    long long numerator() const;
    long long denominator() const;
    auto setnumerator(long long nv);
    auto setdenominator(long long nv);

    double value() const;

    Fraction reciprocal() const;

    std::string str(size_t mode = 0) const;

    bool operator==(const Fraction& f) const;
    auto operator<=>(const Fraction& f) const;
    bool operator==(size_t s) const;
    auto operator<=>(size_t s) const;
    friend bool operator== (size_t s, Fraction& f);
    friend auto operator<=> (size_t s, Fraction& f);
    bool operator==(double d) const;
    auto operator<=>(double d) const;
    friend bool operator== (double d, Fraction& f);
    friend auto operator<=> (double d, Fraction& f);

    Fraction operator+(const Fraction& f) const;
    Fraction operator+(size_t s) const;
    Fraction operator+(double d) const;
    friend Fraction operator+(size_t s, const Fraction& f);
    friend Fraction operator+(double d, const Fraction& f);

    Fraction operator-(const Fraction& f) const;
    Fraction operator-(size_t s) const;
    Fraction operator-(double d) const;
    friend Fraction operator-(size_t s, const Fraction& f);
    friend Fraction operator-(double d, const Fraction& f);

    Fraction operator*(const Fraction& f) const;
    Fraction operator*(size_t s) const;
    Fraction operator*(double d) const;
    friend Fraction operator*(size_t s, const Fraction& f);
    friend Fraction operator*(double d, const Fraction& f);

    Fraction operator/(const Fraction& f) const;
    Fraction operator/(size_t s) const;
    Fraction operator/(double d) const;
    friend Fraction operator/(size_t s, const Fraction& f);
    friend Fraction operator/(double d, const Fraction& f);

    Fraction operator%(const Fraction& f) const;
    Fraction operator%(size_t s) const;
    Fraction operator%(double d) const;
    friend size_t operator%(size_t s, const Fraction& f);
    friend double operator%(double d, const Fraction& f);

    Fraction& operator+=(const Fraction& f);
    Fraction& operator+=(size_t s);
    Fraction& operator+=(double d);
    friend size_t operator+=(size_t s, Fraction& f);
    friend double operator+=(double d, Fraction& f);

    Fraction& operator-=(const Fraction& f);
    Fraction& operator-=(size_t s);
    Fraction& operator-=(double d);
    friend size_t operator-=(size_t s, Fraction& f);
    friend double operator-=(double d, Fraction& f);

    Fraction& operator*=(const Fraction& f);
    Fraction& operator*=(size_t s);
    Fraction& operator*=(double d);
    friend size_t operator*=(size_t s, Fraction& f);
    friend double operator*=(double d, Fraction& f);

    Fraction& operator/=(const Fraction& f);
    Fraction& operator/=(size_t s);
    Fraction& operator/=(double d);
    friend size_t operator/=(size_t s, Fraction& f);
    friend double operator/=(double d, Fraction& f);

    Fraction& operator%=(const Fraction& f);
    Fraction& operator%=(size_t s);
    Fraction& operator%=(double d);
    friend size_t operator%=(size_t s, Fraction& f);
    friend double operator%=(double d, Fraction& f);

    Fraction& operator++();
    Fraction operator++(int);
    Fraction& operator--();
    Fraction operator--(int);

    Fraction operator+();
    Fraction operator-();
    long long operator[](int i);
};

#include "Fraction.h"
#include <limits>
#include <sstream>

Fraction::Fraction(double numerator, double denominator)
{
    double tsn{ numerator }, tsd{ denominator };
    while ((static_cast<long long>(tsn) != tsn || static_cast<long long>(tsd) != tsd) && std::numeric_limits<long long>::max() / 10 > tsn && std::numeric_limits<long long>::max() / 10 > tsd) {
        tsn *= 10;
        tsd *= 10;
    }
    num = tsn;
    denom = tsd;
    simplify();
}

Fraction::Fraction(double numerator, double denominator, int integer_part)
{
    numerator += denominator * integer_part;
    double tsn{ numerator }, tsd{ denominator };
    while ((static_cast<long long>(tsn) != tsn || static_cast<long long>(tsd) != tsd) && std::numeric_limits<long long>::max() / 10 > tsn && std::numeric_limits<long long>::max() / 10 > tsd) {
        tsn *= 10;
        tsd *= 10;
    }
    num = tsn;
    denom = tsd;
    simplify();
}

Fraction::Fraction(const Fraction& f)
{
    num = f.numerator();
    denom = f.denominator();
}

long long Fraction::numerator() const
{
    return num;
}

long long Fraction::denominator() const
{
    return denom;
}

auto Fraction::setnumerator(long long nv)
{
    num = nv;
    simplify();
    return this;
}

auto Fraction::setdenominator(long long nv)
{
    denom = nv;
    simplify();
    return this;
}

double Fraction::value() const
{
    return static_cast<double>(num) / denom;
}

Fraction Fraction::reciprocal() const
{
    return Fraction(denom, num);
}

std::string Fraction::str(size_t mode) const 
{
    std::stringstream ss;
    if (mode == 0) {
        ss << num;
        if (denom != 1) {
            ss << '/' << denom;
        }
    }
    else {
        if (num % denom == 0 || denom == 1) {
            ss << num / denom;
        }
        else {
            if (abs(denom) > abs(num)) {
                ss << num << '/' << denom;
            }
            else if (num < 0) {
                ss << '-' << '(' << (num / denom) << ' ' << -(num % denom) << '/' << denom << ')';
            }
            else {
                ss << (num / denom) << ' ' << num % denom << '/' << denom;
            }
        }
    }
    return ss.str();
}

bool Fraction::operator==(const Fraction& f) const
{
    return value() == f.value();
}

auto Fraction::operator<=>(const Fraction& f) const 
{
    return value() <=> f.value();
}

bool Fraction::operator==(size_t s) const 
{
    return value() == s;
}

auto Fraction::operator<=>(size_t s) const 
{
    return value() <=> s;
}

bool operator==(size_t s, const Fraction& f)
{
    return s == f.value();
}

auto operator<=>(size_t s, const Fraction& f)
{
    return s <=> f.value();
}

bool Fraction::operator==(double d) const
{
    return value() == d;
}

auto Fraction::operator<=>(double d) const
{
    return value() <=> d;
}

bool operator==(double d, Fraction& f)
{
    return f.value() == d;
}

auto operator<=>(double d, Fraction& f)
{
    return f.value() <=> d;
}

Fraction Fraction::operator+(const Fraction& f) const
{
    return Fraction(num * f.denominator() + f.numerator() * denom, denom * f.denominator());
}

Fraction Fraction::operator+(size_t s) const
{
    return Fraction(s * denom + num, denom);
}

Fraction Fraction::operator+(double d) const
{
    return *this + Fraction(d);
}

Fraction operator+(size_t s, const Fraction& f)
{
    return f + s;
}

Fraction operator+(double d, const Fraction& f)
{
    return f + d;
}

Fraction Fraction::operator-(const Fraction& f) const
{
    return Fraction(num * f.denominator() - f.numerator() * denom, denom * f.denominator());
}

Fraction Fraction::operator-(size_t s) const
{
    return Fraction(num - (s * denom), denom);
}

Fraction Fraction::operator-(double d) const
{
    return *this - Fraction(d);
}

Fraction operator-(size_t s, const Fraction& f)
{
    return Fraction(s * f.denom - f.num, f.denom);
}

Fraction operator-(double d, const Fraction& f)
{
    return Fraction(d) - f;
}

Fraction Fraction::operator*(const Fraction& f) const
{
    return Fraction(num * f.numerator(), denom * f.denominator());
}

Fraction Fraction::operator*(size_t s) const
{
    return Fraction(num * s, denom);
}

Fraction Fraction::operator*(double d) const
{
    return Fraction(num * d, denom);
}

Fraction operator*(size_t s, const Fraction& f)
{
    return Fraction(f.numerator() * s, f.denominator());
}

Fraction operator*(double d, const Fraction& f)
{
    return Fraction(f.numerator() * d, f.denominator());
}

Fraction Fraction::operator/(const Fraction& f) const
{
    return (*this) * f.reciprocal();
}

Fraction Fraction::operator/(size_t s) const
{
    return Fraction(num, denom * s);
}

Fraction Fraction::operator/(double d) const
{
    return Fraction(num, denom * d);
}

Fraction operator/(size_t s, const Fraction& f)
{
    return s * f.reciprocal();
}

Fraction operator/(double d, const Fraction& f)
{
    return d * f.reciprocal();
}

Fraction Fraction::operator%(const Fraction& f) const
{
    return ((*this) / f).value() > 0 ? Fraction((*this) - (floor(((*this) / f).value()) * f)) : Fraction((*this) - (ceil(((*this) / f).value()) * f));
}

Fraction Fraction::operator%(size_t s) const
{
    return ((*this) / s).value() > 0 ? Fraction((*this) - (floor(((*this) / s).value()) * s)) : Fraction((*this) - (ceil(((*this) / s).value()) * s));
}

Fraction Fraction::operator%(double d) const
{
    return ((*this) / d).value() > 0 ? Fraction((*this) - (floor(((*this) / d).value()) * d)) : Fraction((*this) - (ceil(((*this) / d).value()) * d));
}

size_t operator%(size_t s, const Fraction& f)
{
    return (f / s).value() > 0 ? ((f) - (floor((s / f).value()) * f)).value() : ((f)-(ceil((s / f).value()) * f)).value();
}

double operator%(double d, const Fraction& f)
{
    return (f / d).value() > 0 ? ((f)-(floor((d / f).value()) * f)).value() : ((f)-(ceil((d / f).value()) * f)).value();
}

Fraction& Fraction::operator+=(const Fraction& f)
{
    *this = *this + f;
    return *this;
}

Fraction& Fraction::operator+=(size_t s)
{
    *this = *this + s;
    return *this;
}

Fraction& Fraction::operator+=(double d)
{
    *this = *this + d;
    return *this;
}

size_t operator+=(size_t s, Fraction& f)
{
    s += round(f.value());
    return s;
}

double operator+=(double d, Fraction& f)
{
    d += f.value();
    return d;
}

Fraction& Fraction::operator-=(const Fraction& f)
{
    *this = *this - f;
    return *this;
}

Fraction& Fraction::operator-=(size_t s)
{
    *this = *this - s;
    return *this;
}

Fraction& Fraction::operator-=(double d)
{
    *this = *this - d;
    return *this;
}

size_t operator-=(size_t s, Fraction& f)
{
    s -= round(f.value());
    return s;
}

double operator-=(double d, Fraction& f)
{
    d -= f.value();
    return d;
}

Fraction& Fraction::operator*=(const Fraction& f)
{
    *this = *this * f;
    return *this;
}

Fraction& Fraction::operator*=(size_t s)
{
    *this = *this * s;
    return *this;
}

Fraction& Fraction::operator*=(double d)
{
    *this = *this * d;
    return *this;
}

size_t operator*=(size_t s, Fraction& f)
{
    s *= round(f.value());
    return s;
}

double operator*=(double d, Fraction& f)
{
    d *= f.value();
    return d;
}

Fraction& Fraction::operator/=(const Fraction& f)
{
    *this = *this / f;
    return *this;
}

Fraction& Fraction::operator/=(size_t s)
{
    *this = *this / s;
    return *this;
}

Fraction& Fraction::operator/=(double d)
{
    *this = *this / d;
    return *this;
}

size_t operator/=(size_t s, Fraction& f)
{
    s /= round(f.value());
    return s;
}

double operator/=(double d, Fraction& f)
{
    d /= f.value();
    return d;
}

Fraction& Fraction::operator%=(const Fraction& f)
{
    *this = *this % f;
    return *this;
}

Fraction& Fraction::operator%=(size_t s)
{
    *this = *this % s;
    return *this;
}

Fraction& Fraction::operator%=(double d)
{
    *this = *this % d;
    return *this;
}

size_t operator%=(size_t s, Fraction& f)
{
    s = s % f;
    return s;
}

double operator%=(double d, Fraction& f)
{
    d = d % f;
    return d;
}

Fraction& Fraction::operator++()
{
    this->num += this->denom;
    return *this;
}

Fraction Fraction::operator++(int)
{
    Fraction copy{ *this };
    this->num += this->denom;
    return copy;
}

Fraction& Fraction::operator--()
{
    this->num -= this->denom;
    return *this;
}

Fraction Fraction::operator--(int)
{
    Fraction copy{ *this };
    this->num -= this->denom;
    return copy;
}

Fraction Fraction::operator+()
{
    return *this;
}

Fraction Fraction::operator-()
{
    return Fraction(-num, denom);
}

long long Fraction::operator[](int i)
{
    return i == 0 ? num : denom;
}