对于任何有限的浮点数值,x - x == 0是否保证成立?

8

浮点数 的值是不精确的,这就是为什么我们很少在比较中使用严格的数字相等性。例如,在 Java 中,这将打印false如 ideone.com 上所见):

System.out.println(.1 + .2 == .3);
// false

通常比较浮点数计算结果的正确方法是查看与某个期望值的绝对差是否小于一定容忍度epsilon
System.out.println(Math.abs(.1 + .2 - .3) < .00000000000001);
// true

这个问题是关于是否有一些操作可以产生精确的结果。我们知道对于任何非有限浮点值x(即NaN或无穷大),x - x总是ALWAYS NaN。但如果x是有限的,这些操作中有没有任何一个是保证的呢?
  1. x * -1 == -x
  2. x - x == 0

(特别是,我最感兴趣的是Java的行为,但其他语言的讨论也欢迎。)


就这个问题而言,我认为(可能我错了)答案是是的!我认为这取决于对于任何有限的IEEE-754浮点值,它的加法逆元是否总是可以精确计算。由于例如floatdouble具有一个专门用于符号的位, 这似乎是成立的,因为它只需要翻转符号位来找到加法逆元(即尾数应该保持不变)。

相关问题


2
这个问题让我有点费解,所以我无法做出贡献,但我刚刚查看了你提供的ideone.com链接...这个网站看起来很酷! - BG100
1
哇哦!我正在投票关闭自己的问题,因为它是重复的。 - polygenelubricants
2个回答

3
两个等式在IEEE 754浮点数中是有保证的,因为x-xx * -1的结果都可以精确表示为与x相同精度的浮点数。在这种情况下,无论舍入模式如何,符合规范的实现都必须返回精确值。
编辑:与.1 + .2示例比较。
在IEEE 754中,您无法将.1.2相加,因为您无法将它们表示为可传递给+的数字。加法、减法、乘法、除法和平方根返回唯一的浮点值,具体取决于舍入模式,它立即低于、立即高于、最接近一个处理关系的规则的值,...,在R上对相同参数执行操作的结果。因此,当结果(在R中)恰好可以表示为浮点数时,无论舍入模式如何,该数字都自动成为结果。
您编译器让您使用0.1作为不同可表示数字的简写而没有警告,这一事实与这些操作的定义无关。例如,当您编写- (0.1)时,-是精确的:它返回其参数的相反数。另一方面,它的参数不是0.1,而是您编译器使用的double
简而言之,x * (-1)操作精确的另一个原因是-1可以表示为double

部分原因是减法和乘法,以及加法、除法和平方根等基本运算是IEEE 754规定的“最优”结果所必需的。 - Pascal Cuoq
“最优”的定义需要澄清,因为你可以争辩说,也许对于.1 + .2 == .3来说这是“最优”的,但我认为在所有IEEE-754 double实现中都是false(除非我忽略了其他问题)。 - polygenelubricants

2
尽管x-x可能会给你-0而不是真正的0,但是-00相等,所以您可以放心地假设任何有限数字减去自身将与零相等。请参阅这里了解更多详情。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接