1

我有以下问题。我用 C++ 写了一个有理数类。类和运算符工作正常,除非分子大于分母。

例如,我使用了 -3/12 和 4/3 =13/12 但我得到的是 3/4

头文件:

#ifndef _FRAC_
#define _FRAC_

#include <iostream>
#include <string>

class frac
{
private:
long numerator, denominator;
long gcd(long, long);
void reduce(const long, const long);
public:
frac(long z = 0, long n = 1);

const float frac::getq();
const std::string frac::getstr();
frac operator-() const
{
    return frac(-numerator, denominator);
}
frac& operator+=(const frac& a)
{
    numerator = a.numerator * denominator + numerator * a.denominator;
    denominator *= a.denominator;
    reduce(numerator, denominator);
    return *this;
}
frac& operator-=(const frac& a)
{
    *this += -a;
    reduce(numerator, denominator);
    return *this;
}
frac& operator++() //Präfix
{
    numerator += denominator;
    reduce(numerator, denominator);
    return *this;
}
frac& operator++(int empty) //Postfix
{
    numerator += denominator;
    reduce(numerator, denominator);
    return *this;
}
frac& operator--() //Präfix
{
    numerator -= denominator;
    reduce(numerator, denominator);
    return *this;
}
frac& operator--(int empty) //Postfix
{
    numerator -= denominator;
    reduce(numerator, denominator);
    return *this;
}
frac& operator*=(const frac& a)
{
    numerator = a.numerator * numerator;
    denominator = a.denominator * denominator;
    reduce(numerator, denominator);
    return *this;
}
frac& operator/=(const frac& a)
{
    numerator = a.denominator * numerator;
    denominator = a.numerator * denominator;
    if (denominator < 0)
    {
        numerator = -numerator;
        denominator = -denominator;
    }
    reduce(numerator, denominator);
    return *this;
}
friend frac operator+ (const frac&, const frac&);
friend frac operator- (const frac&, const frac&);
friend frac operator* (const frac&, const frac&);
friend frac operator/ (const frac&, const frac&);

friend std::ostream& operator<< (std::ostream& os, const frac& a);
friend std::istream& operator>> (std::istream& is, frac& a);
};

#endif

主.cpp

#include <iostream>
#include <sstream>
#include "FRAC.h"

using namespace std;

frac::frac(long z, long n)
{
if (n < 0)
{
    z = -z;
    n = -n;
}
numerator = z;
denominator = n;
}



const float frac::getq()
{
return static_cast<float>(numerator) / static_cast<float>(denominator);
}

const string frac::getstr()
{
reduce(numerator, denominator);
ostringstream z, n;
z << numerator;
n << denominator;
if (numerator == 0) 
    return "0";
else if (denominator == 1) 
    return z.str();
else if (numerator == denominator) 
    return "1";
else
    return z.str() + "/" + n.str();
}
//greatest common divisor
long frac::gcd(long z, long n)
{

z = abs(z);
n = abs(n);
if (n > z)
    return gcd(n, z);
else if (n != 0)
    return gcd(n, z % n);
else
    return z; 
}

void frac::reduce(const long z, const long n)
{
numerator /= gcd(z, n);
denominator /= gcd(z, n);
}

frac operator+(const frac& a, const frac& b)
{
frac temp;
temp.denominator = a.denominator * b.denominator;
temp.numerator = a.numerator * b.denominator + b.numerator * a.denominator;
temp.reduce(temp.numerator, temp.denominator);
return temp;
}

frac operator-(const frac& a, const frac& b)
{
frac temp = a;
temp += -b;
temp.reduce(temp.numerator, temp.denominator);
return temp;
}

frac operator*(const frac& a, const frac& b)
{
frac temp;
temp.numerator = a.numerator * b.numerator;
temp.denominator = a.denominator * b.denominator;
temp.reduce(temp.numerator, temp.denominator);
return temp;
}

frac operator/(const frac& a, const frac& b)
{
frac temp;
temp.numerator = a.numerator * b.denominator;
temp.denominator = a.denominator * b.numerator;
if (temp.denominator < 0)
{
    temp.numerator = -temp.numerator;
    temp.denominator = -temp.denominator;
}
temp.reduce(temp.numerator, temp.denominator);
return temp;
}

ostream& operator<<(ostream& os, const frac& a)
{
frac temp;
temp.numerator = a.numerator;
temp.denominator = a.denominator;
temp.reduce(temp.numerator, temp.denominator);
if (temp.numerator == 0) //intstead of 0/1 -> 0 
    os << "0";
else if (temp.denominator == 1) //instead of 3/1 -> 3 
    os << temp.numerator;
else if (temp.numerator == temp.denominator) //instead of 3/3 -> 1 
    os << "1";
else
    os << temp.numerator << "/" << temp.denominator;
return os;
}

istream& operator>>(istream& is, frac& a)
{
is >> a.numerator;
is >> a.denominator;
if (!is)
    return is;
if (a.denominator < 0)
{
    a.numerator = -a.numerator;
    a.denominator = -a.denominator;
}
return is;
}

// 
int main()
{
frac x(-3, 12), y(4 / 3), z;

z = x + y;
cout << z;
// i simply used that visual studio doesn't close the console
// z is 4/3 instead of 13/12
cin >> z;
return 0;
}

我认为问题出在 operator+ 方法、gcd 函数或 reduce...

我希望有人能帮帮忙 :)

问候和感谢

托马斯^^

4

1 回答 1

0

问题在于您的测试代码:

frac x(-3, 12), y(4 / 3), z;

应该:

frac x(-3, 12), y(4, 3), z;

您将 y 初始化为 1 / 1,因为 4 / 3 = 1(整数除法)并且分母的默认参数是 1。

-3/12 + 1 = 3/4

于 2015-03-22T07:43:55.887 回答