浮点数比较精度

5

如果给定 3 个 IEEE-754 浮点数 a、b、c,它们都不是 +/-INF 或 NaN,并且 a < b,则可以安全地假设 a - c < b - c 吗?或者,您能否提供一个此情况不正确的示例?


强制链接:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html - Robᵩ
1个回答

11
假设a约为0.00000000000000001,b约为0.00000000000000002,c等于1。那么a - cb - c都将等于-1。(这是基于双精度,即64位值的假设。对于更高精度的值,您需要添加更多的零。)

编辑添加解释:

如果我们忽略非规范化值、非数字值、无穷大等,只关注IEEE 754双精度浮点数,以便有具体的东西来看,那么从二进制表示来看,浮点数由一个符号位s(正数为0,负数为1)、一个11位指数e(偏移量为1023,因此e=0表示2−1023e=1023表示20,即1),和一个52位定点小数尾数m(代表二进制点后52个位置,因此它在[0,1)之间具有有限精度)。因此,该表示的实际值为(−1)s × (1 + m) × 2e−1023

由于尾数是定点的,且具有固定的位数,因此精度非常有限。像1.00000000000000001和1.00000000000000002这样的值,在小数点后面有很多位是相同的,比双精度尾数能够保存的位数还要多。
当你在一个非常大的数字和一个非常小的数字之间执行加法或减法(相对于彼此而言:在我们的例子中,1是“非常大的”;或者,我们可以使用1作为非常小的值,并选择一个非常大的值10000000000000000),结果的指数将几乎完全由非常大的数字决定,并且非常小的数字的尾数必须相应地缩放。在我们的例子中,它被约除以10的17次方;因此它就消失了。尾数没有足够的位数来区分它。

太快了,谢谢 :) 我甚至还没来得及接受它。另外,也许你可以简单解释一下为什么会发生这种情况。 - user16367
IEEE 754 64位二进制浮点数的指数范围为-1022(而不是-1024)到1023。(此外,小数部分应该称为有效数字,而不是尾数。) - Eric Postpischil
@EricPostpischil:谢谢。我写的解释太快了,除了你指出的问题之外,还有一些其他不太正确的地方。(例如,我使用了一种“逻辑”符号 1-1 和一个带符号整数的“逻辑”指数,但使用实际的符号位 01 和一个位运算指数可能更合理,需要从中减去 1023 。)唉,好吧。我认为这已经足够回答这个问题,但我会思考如何使其更精确。(或者,您可以随意自行编辑它。) - ruakh

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