浮点数使用相等性进行比较的情况

时间:2014-06-11 07:27:58

标签: c++ floating-point

最近我讨论了浮点比较。我的观点总是不直接使用==比较两个浮点数。

有人指出这不是真的,有些情况下使用==完全没问题。 我可以想到典型的情况,我检查IEEE 754文字,+-INF+-0,但除此之外,我想不出这不会导致问题的情况。

所以我的问题是:使用==的浮点数比较有效时会出现什么情况?

3 个答案:

答案 0 :(得分:5)

双精度浮点表示(每个数字64位)对于整数最高为+ + 2 ** 53( - + 9,007,199,254,740,992)。如果您使用的是浮点数,但是从整数开始并使用它们进行整数计算,并且您从未通过该限制,那么结果就是精确的,使用==就完全没问了。

通常可以精确表示的数字是N / M,其中N是整数,M是2的幂。因此,如果您只是进行涉及例如的计算。它们的1 / 4,1 / 2,3 / 4和整数倍也很好,直到达到很大的乘数。

相反,当您处理无法准确表示的数字(例如0.1)时,近似值会导致我产生令人惊讶的结果。问题的一个原因是中间结果可能以更高的精度存储在临时值中,因此公式的结果可能会有所不同,具体取决于您是否明确地将其存储在内存中,并且它也可能根据优化级别而改变。

答案 1 :(得分:1)

以下是浮点相等的有效用法的一些示例:

  • 将某个函数记录为在某些情况下返回HUGE_VALdetermining whether this happenedresult == HUGE_VAL

  • 确定双d是否包含可表示为floatd == (double)(float)d的数字。我实际上在我的日常工作中使用它,因为我使用双对来表示double值的间隔和float值的间隔,并且有一些点可以断言浮点数的间隔的边界是很好的。浮动。

  • 确定浮点数y是否为NaNy == y

  • 确定带有y的浮点数y - y == 0.0 is infinity or NaN(有限值y是否使条件成立,NaN和无穷大把它变成假的。)

  • 确定是否在浮点数的有效位中设置了一个位,如下例所示,取自this rant

    /* coef is a power of two plus one. */
    double t = coef * f;
    double o = f - t + t - f;
    if (o != 0)
    {
      ...
    

答案 2 :(得分:0)

浮点数表示使用相应基数(通常为2)的精确值。使用相等性来比较它们是没有错的。

二进制浮点数不能精确地表示所有十进制值,但是,对于大多数小数十进制值,二进制浮点将使用近似值。只要十进制数不超过std::numeric_limits<F>::digits10,结果表示也在系统内唯一标识(对于某些十进​​制值,在两个二进制表示之间存在一个小数,在这种情况下,舍入方向应该选择正确的)。

使浮点数成为奇怪的问题是计算导致值的舍入,并且取决于何时发生舍入,假定精确操作是不精确的,并且评估顺序很重要。对舍入值进行算术将相应地增加误差并产生与获得的值不同的值,例如通过从十进制值到二进制浮点的转换。您可能不希望对计算结果使用相等的操作。