是否存在x的浮点值,xx == 0是否为false?

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 - NaNNaN.它是真实的,但是,对于任何有限浮点数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是某些计算的结果,而不是常量,可代表的价值).这是这些平台上的数字模型中的一个错误,但这并不意味着它不会发生.

  • @Potatoswatter:作为754标准草案的编辑花了几个月的时间是有帮助的.没有那个背景,我不知道在哪里寻找这些东西. (10认同)