【发布时间】:2018-12-10 13:18:35
【问题描述】:
众所周知,在比较浮点值时必须小心。通常,我们不使用 ==,而是使用一些基于 epsilon 或 ULP 的相等性测试。
但是,我想知道,是否有任何情况下,使用== 完全没问题?
看看这个简单的sn-p,哪些情况可以保证成功?
void fn(float a, float b) {
float l1 = a/b;
float l2 = a/b;
if (l1==l1) { } // case a)
if (l1==l2) { } // case b)
if (l1==a/b) { } // case c)
if (l1==5.0f/3.0f) { } // case d)
}
int main() {
fn(5.0f, 3.0f);
}
注意:我检查了 this 和 this,但它们并没有涵盖我的(所有)案例。
注2:看来我必须添加一些附加信息,所以答案在实践中可能会有用:我想知道:
- C++ 标准是怎么说的
- 如果 C++ 实现遵循 IEEE-754 会发生什么
这是我在current draft standard中找到的唯一相关声明:
浮点类型的值表示是实现定义的。 [ 注:本文档对浮点运算的准确性没有要求;另见 [support.limits]。 — 尾注 ]
那么,这是否意味着,即使是“case a)”也是实现定义的?我的意思是,l1==l1 绝对是一个浮点运算。那么,如果一个实现是“不准确的”,那么l1==l1 可能是假的吗?
我认为这个问题不是Is floating-point == ever OK? 的重复问题。这个问题没有解决我要问的任何情况。相同的主题,不同的问题。我想有专门针对案例 a)-d) 的答案,但我无法在重复的问题中找到答案。
【问题讨论】:
-
@interjay:是的,我也是这么想的,但我不能 100% 确定。 IEEE 754 规定了这一点,但我不知道 C++ 标准对此有何规定,如果有的话。
-
根本无法保证。
-
您永远需要的答案:永远不要
==。 -
@iBug:你能解释一下原因吗?
标签: c++ floating-point language-lawyer precision floating-point-comparison