And*_*ker 21 floating-point floating-accuracy ieee-754
在大多数情况下,我理解浮点比较测试应该使用一系列值(abs(xy)<epsilon)来实现,但自减法是否意味着结果为零?
// can the assertion be triggered?
float x = //?;
assert( x-x == 0 )
Run Code Online (Sandbox Code Playgroud)
我的猜测是nan/inf可能是特殊情况,但我对简单值发生的事情更感兴趣.
编辑:
如果有人可以引用参考(IEEE浮点标准),我很乐意选择答案吗?
Ste*_*non 59
正如你暗示inf - inf
的那样NaN
,它不等于零.同样,NaN - NaN
是NaN
.它是真实的,但是,对于任何有限浮点数x
,x - x == 0.0
(取决于舍入模式,结果x - x
可能是负零,但负零比较等于0.0
在浮点运算).
编辑:提供明确的标准参考有点棘手,因为这是IEEE-754标准中规定的规则的新兴属性.具体而言,它要求第5章中定义的操作被正确舍入.减法就是这样一种操作(第5.4.1节"算术运算"),正确舍入的结果x - x
是适当符号的零(第6.3节,第3段):
当具有相反符号的两个操作数的总和(或具有相同符号的两个操作数的差异)恰好为零时,除了roundTowardNegative之外,在所有舍入方向属性中该和(或差)的符号应为+0; 在该属性下,精确零和(或差)的符号应为-0.
所以结果x - x
必须是+/- 0
,因此必须相等0.0
(第5.11节,第2段):
比较应忽略零的符号.
进一步编辑:这并不是说错误的编译器不能导致该断言触发.你的问题含糊不清; 没有有限的浮点数x
,这x - x == 0
是假的.但是,这不是您发布的代码检查的内容; 它检查C风格语言中的某个表达式是否可以计算为非零值; 特别是在某些平台上,某些(错误构思的)编译器优化,该x
表达式中变量的两个实例可能具有不同的值,导致断言失败(特别是如果x
是某些计算的结果,而不是常量,可代表的价值).这是这些平台上的数字模型中的一个错误,但这并不意味着它不会发生.