众所周知,在比较浮点值时必须小心.通常,==我们使用一些基于epsilon或ULP的相等测试来代替使用.
但是,我想知道,有什么案例,使用时==完全没问题吗?
看看这个简单的片段,哪些案例可以保证成功?
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);
}
Run Code Online (Sandbox Code Playgroud)
注意:我已经检查了这个和这个,但它们不包括(全部)我的情况.
注2:似乎我必须添加一些加号信息,所以答案在实践中很有用:我想知道:
这是我在目前的标准草案中找到的唯一相关陈述:
浮点类型的值表示是实现定义的.[注意:本文档对浮点运算的准确性没有要求; 另见[support.limits]. - 结束说明]
那么,这是否意味着甚至"案例a)"是实现定义的?我的意思是,l1==l1绝对是一个浮点运算.那么,如果一个实现是"不准确的",那么可能l1==l1是假的?
我认为这个问题不是重复的浮点数==永远好吗?.这个问题没有解决我提出的任何案件.同一主题,不同的问题.我想特别针对案例a)-d)得到答案,因为我无法在重复的问题中找到答案.
c++ floating-point precision language-lawyer floating-point-comparison
对于浮点值,是否保证a + b == b + a?
我相信这在IEEE754中是有保证的,但是C++标准没有规定必须使用IEEE754.唯一相关的文本似乎来自[expr.add]#3:
binary +运算符的结果是操作数的总和.
数学运算"和"是可交换的.然而,数学运算"sum"也是关联的,而浮点加法肯定不是关联的.所以,在我看来,我们不能断定数学中"和"的交换性意味着这个引用指的是C++中的交换性.