为什么90-.Machine $ double.eps小于90?

时间:2018-12-07 07:40:40

标签: r floating-accuracy

在这里我对精度的了解一定会有所遗漏,但是我认为R可以代表步长为.Machine$double.eps的网格上的数字,但是事实并非如此。实际上:

90 - .Machine$double.eps == 90
# [1] TRUE

这对我来说很奇怪,因为这两个数字(1)可以表示,而(2)不为零:

sprintf('%.16a', c(90, .Machine$double.eps))
# [1] "0x1.6800000000000000p+6"  "0x1.0000000000000000p-52"

差异在数值上非零的第一位甚至更具启发性:

90 - 32*.Machine$double.eps < 90
# [1] FALSE
90 - 33*.Machine$double.eps < 90
# [1] TRUE

这种结果直接指向精度问题,但是我的理解在这里有一定的差距...

如果90 - .Machine$double.eps == 90为何在我的计算机上没有double.eps大?

这里的结果告诉我,实际上我应该有.Machine$double.eps == 2^5 * .Machine$double.eps ...

1 个答案:

答案 0 :(得分:4)

这种效果称为重要性丢失https://en.wikipedia.org/wiki/Loss_of_significance)。 90的有效数字会将.Machine$double.eps移开。尝试

(90 - 46*.Machine$double.eps) == 90

这应该给您FALSE
machine.eps的定义:它是最低值eps1+eps不是1

根据经验(假设浮点数以2为底):
这个eps使得范围1 .. 2,
有所不同。 对于范围2 .. 4的精度为2*eps
等等。

x <- 3.8
(x + 2*.Machine$double.eps) == x
x <- 4
(x + 2*.Machine$double.eps) == x
# ...
x <- 63
(x + 32*.Machine$double.eps) == x
x <- 64
(x + 32*.Machine$double.eps) == x

浮点表示的绝对精度随x的不同而变化,但是相对精度在浮点数范围内几乎是恒定的。