gpt4 book ai didi

c++ - 在c++/分子中实现比分母大的有理数

转载 作者:太空宇宙 更新时间:2023-11-04 13:37:06 25 4
gpt4 key购买 nike

我有以下问题。我用 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

main.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...

希望有人能帮忙:)

问候和感谢

托马斯 ^^

最佳答案

问题出在你的测试代码上:

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

关于c++ - 在c++/分子中实现比分母大的有理数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29191958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com