繁体   English   中英

比较 c++ 中的浮点数

[英]Comparing floats in c++

我正在从教程中学习 c++,在那里,有人告诉我比较 c++ 中的浮点数可能非常令人困惑。 例如,在下面的代码中:

#include <iostream>

using namespace std;

int main()
{
    float decimalNumber = 1.2;
    
    if (decimalNumber == 1.2){
        cout << "Equal" << endl;
    }else{
        cout << "Not equal" << endl;
    }

    return 0;
}

我会得到“不相等”。 我同意这一点。 导师告诉如果我们需要比较浮点数,我们可以使用 > 到最接近的数字。 (这不是很精确)。 我在谷歌搜索了不同的方法来比较浮点数,我得到了许多复杂的方法来做到这一点。

然后我自己创建了一个程序:

#include <iostream>

using namespace std;

int main()
{
    float decimalNumber = 1.2;
    
    if (decimalNumber == (float)1.2){
        cout << "Equal" << endl;
    }else{
        cout << "Not equal" << endl;
    }

    return 0;
}

在像上面那样进行类型转换之后,我得到了“Equal”。

我想知道的是我应该使用上述方法来比较我所有程序中的浮点数吗? 这有一些缺点吗?

注意:我知道数字在 memory 中的精确表示方式以及另一个SO Question中描述的 0.1 + 0.2.- 0.3 的方式。 我只想知道我可以通过上述方式检查两个浮点数的相等性吗?

我想知道的是我应该使用上述方法来比较我所有程序中的浮点数吗?

取决于上下文。 等式比较对浮点数很少有用。

但是,是的,无论是比较相等性还是关系性,都应该比较相同类型的浮点对象,而不是混合浮点数和双精度数。

这有一些缺点吗?

浮点计算可能有错误。 结果可能不是你所期望的。 当有错误时,相等比较是没有意义的。

第二个例子起作用的原因在某种程度上纯粹是偶然的。

需要考虑的一些因素:

  1. 当比较的双方都是float类型时,编译器可能更有可能“优化”比较,以便它只发生在编译过程中。 它可以查看文字并意识到这两个数字在逻辑上是相同的,即使在运行时它们可能在较低的精度级别上有所不同。

  2. 当比较的两边都是float类型时,它们具有相同的精度,因此如果您以相同的方式(这里,通过文字)创建值,则较低精度级别的任何错误都可能相同。 当其中一个是double时,最后会有额外的错误位导致比较失败。 如果您通过0.6 + 0.6创建了一个,那么结果也可能不同,因为错误传播方式不同。

一般来说,不要依赖这个。 当浮点数包含不能以二进制精确表示的数字时,您无法真正预测它们的“准确度”。 如果您需要松散的值比较,您应该坚持使用 epsilon-range 比较(在适当的情况下),即使直接比较在没有它的情况下偶尔会“起作用”。

如果您实际上不需要浮点数,一个好方法是使用定点数。 该语言中没有内置的定点类型,但这没关系,因为您可以通过一些算术简单地模拟它们。 很难知道您的用例是什么,但是如果您只需要一位小数,则可以存储int decimalNumber = 12 (即,将小数点移动一位)并在需要显示时除以十。 两个值为12int总是比较好。

金钱就是一个很好的例子:用便士(或十分之一便士)而不是英镑来计算,以避免在骗取客户现金时出现错误。

默认情况下,在 C++ 中,浮点数与浮点变量相比被视为double精度数。 您需要使用f后缀告诉编译器该数字是浮点数而不是double 举个例子:

#include <iostream>

int main(void) {
    float dec = 1.2;

    if (dec == 1.2f)
        std::cout << "Equal";
    else
        std::cout << "Unequal";
    
    return 0;
}

它会产生Equal OTOH,如果您不使用f后缀,则比较将等效于:

if (dec == 1.199999999999999956) // 1.2 converted into double

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM