分数布尔运算符

Fraction Boolean Operators

我有比较两个分数 classes 的代码,我的 class 运算符在下面

// Equal to (==)
        bool Fraction::operator == (const Fraction &fraction){
            if (static_cast<double>(numerator / denominator) == static_cast<double>(fraction.numerator / fraction.denominator)){
                return true;
            } else {
                return false;
            }
        } // End of == operator
.
.
.
. // And so on for all other comparisons

但是我的输出 return 是 (==)、(<=) 和 (>=) 运算符,表示它们都是真的。

在我的 main()

// EQUAL TO
        if (fraction1 == fraction2){
            cout << fraction1.toString() << " is equal to " << fraction2.toString() << "." << endl;
        }
.
.
. // And so on...

我也试过 if (fraction1.operator==(fraction2)){ 而不是 if (fraction1 == fraction2) 但它们 return 是同一件事。我坚持这一点,我的逻辑会不会有问题?如果需要,我可以 post 更多代码。谢谢!

编辑:static_cast 应该是双倍的。分子和分母是整数,在我的 setter 和 getter 方法中它们是整数。

if (static_cast<double>(numerator / denominator) == static_cast<float>(fraction.numerator / fraction.denominator)){

这里的第一个问题是,您将其中一个转换为浮动,而将其他转换为加倍。这几乎肯定不是你想要的,首先你应该为你正在比较的两个东西转换为相同的数据类型。虽然由于我接下来概述的错误,它在这种情况下可能会起作用,但您不想直接比较浮点数,请阅读此 https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf 以了解有关这样做的陷阱的更多信息。

我在这里看到的大问题是你有一个整数 div 正在进行,这在某些情况下可能会严重爆炸,例如代码失败的情况:

int numerator1 = 5;
int denominator1 = 2;
int numerator2 = 4;
int denominator2 = 2;

在这种情况下,您基本上得到:

numerator1 / denominator1 == numerator2 / denominator2

这可能不是您想要的。您可以在此处查看实际效果 http://coliru.stacked-crooked.com/a/0eb3723f952fbf4a

假设您将分子和分母存储为整数,那么您可以通过将所有内容都保留为整数来避免相等性测试中的所有浮点数:

if (numerator * fraction.denominator == fraction.numerator * denominator){
    return true;
}else{
    return false;
}

这也避免了之前的bug。鉴于您正在使用一些简单的代数处理有理数,您可以弄清楚如何以类似的方式实现其他操作。如果你这样做,你只需要检查溢出。

如果您在调用 oparator==() 时使用的 class 的所有实例的 numerator 小于 denominator,则 numerator / denominator 将是由于整数除法为零。

那样的话,

if (static_cast<double>(numerator / denominator) == static_cast<float>(fraction.numerator / fraction.denominator)){

相当于:

if (static_cast<double>(0) == static_cast<float>(0)){

这将是 true

如果你的数字不是太大,即没有integer overflow的风险,你可以使用:

if ( this->numerator*fraction.denominator == fraction.numerator*this->denominator )

如果存在整数溢出的风险,您可以将分数转换为实数,但您需要使用公差检查相等性。

double f1 = 1.0*numerator/denominator;
double f2 = 1.0*fraction.numerator/fraction.denominator;

if ( fabs(f1-f2) < **SOME TOLERANCE VALUE** )