我有以下问题。我用 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...
我希望有人能帮帮忙 :)
问候和感谢
托马斯^^