.Machine $ double.eps大于必要的?

时间:2014-01-11 22:17:05

标签: r

该文档将.Machine$double.eps描述为最小的正浮点数x,使1 + x != 1 。所以我希望以下内容产生1:

options(digits=17)
1 + .Machine$double.eps
# [1] 1.0000000000000002

但事实并非如此。在我得到预期的四舍五入之前,似乎我必须低至0.5*.Machine$double.eps。我误解了.Machine$double.eps的某些内容吗?这个平台依赖吗? (下面的sessionInfo())

> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-apple-darwin10.8.0 (64-bit)

locale:
[1] en_CA.UTF-8/en_CA.UTF-8/en_CA.UTF-8/C/en_CA.UTF-8/en_CA.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] tools_3.0.2

谢谢

3 个答案:

答案 0 :(得分:8)

仅仅因为它很有趣,这里是the code R uses to calculate eps(提取到自己的程序中):

#include <stdio.h>

int main() {
    double temp, tempa, a;
    double eps;

    double one = 1;
    double zero = one - one;
    double beta = 2;

    a = 1.38777878078144568e-17;
    for(;;) {
        temp = one + a;
        if (temp - one != zero)
            break;
        a = a * beta;
    }
    eps = a;

    printf("%e\n", eps);
}

如记录所示,它产生2.22e-16。

请注意,它每次跳跃2倍 - 因此它实际上并不会找到1 + x不是1的严格最小浮点数。但它会在2阶的权力阶梯中找到最小的一个。

所以,我会说严格来说文档不太准确,因为0.75*eps + 1 != 10.75*eps < eps确实如此。

答案 1 :(得分:2)

您似乎误解了文档。请注意,它表示x

是最小的1 + x != 1

仔细阅读 - 如果我们向.Machine$double.eps添加1,那么我们不应该得到1回。所以你得到的结果是预期的。

答案 2 :(得分:0)

请注意@Owen发布的算法搜索并找到该号码x

(x+1)-1 == (x*0.51+1)-1 !=  (x*0.5+1)-1    

@ Ben,true,x*0.6 < x,但在评估x+1后,'x',即剩余部分,由于限制而变为.Machine$double.eps0双精度浮点算法。

在我看来,.Machine$double.eps是统一减法残差的最小表示。

因此,.Machine$double.eps确实是最小的正浮点数x,根据有效数字为1 + x!= 1 ,指数为1e0。

详细说明请注意,根据ANSI/IEEE-754 standard,在64位浮点表示中,为尾数(signif数字)保留52位,为指数保留11位,为符号保留1位。 因此,关于尾数的最小可能数(更好:准确度)是位:

0000000000000000000000000000000000000000000000000001(如果数数正确则为52)

这是.Machine$double.eps,因此log2(.Machine$double.eps)返回-52。

(如果 64位双浮点,它将返回其他内容)

此外,自

.Machine$double.eps + 1 = +1000000000000000000000000000000000000000000000000001e00000000000

显而易见,.Machine$double.eps的数字不能小于x+1!=1,因为每个较小的数字都会四舍五入为2^-520另外。