【问题标题】:For any finite floating point value, is it guaranteed that x - x == 0?对于任何有限浮点值,是否保证 x - x == 0?
【发布时间】:2010-08-30 10:35:18
【问题描述】:

Floating point 的值是不精确的,这就是为什么我们应该在比较中很少使用严格的数值相等。例如,在 Java 中,这会打印出 false (as seen on ideone.com):

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

通常比较浮点计算结果的正确方法是查看与某个期望值的绝对差是否小于某个可容忍的epsilon

System.out.println(Math.abs(.1 + .2 - .3) < .00000000000001);
// true

问题在于 一些 操作是否可以产生准确的结果。我们知道对于任何非有限浮点值x(即NaN 或无穷大),x - xALWAYS NaN

但是如果x 是有限的,这是否有任何保证?

  1. x * -1 == -x
  2. x - x == 0

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


对于它的价值,我认为(我可能在这里错了)答案是是的!我认为它归结为是否对于任何有限的IEEE-754 浮点值,它additive inverse 总是可以精确计算的。由于例如floatdoubleone dedicated bit just for the sign,这似乎是这种情况,因为它只需要翻转符号位即可找到加法逆(即 significand 应该保持不变)。

相关问题

【问题讨论】:

标签: language-agnostic floating-point precision ieee-754 signedness


【解决方案1】:

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 规定的“最佳”结果的基本运算。
  • 那么“最优”的定义需要澄清,因为你可以争辩说它对于.1 + .2 == .3 来说可能是“最优的”,但我认为这是false 在所有IEEE-754 double实施(除非我在其他一些问题上遗漏了)。
【解决方案2】:

虽然x - x 可能给你-0 而不是真正的0-0 比较等于0,所以你可以放心地假设任何有限数减去自身将比较等于零.

更多详情请见Is there a floating point value of x, for which x-x == 0 is false?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    • 2016-10-20
    • 2022-01-13
    相关资源
    最近更新 更多