该文档将.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
谢谢
答案 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 != 1
和0.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.eps
或0
双精度浮点算法。
在我看来,.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^-52
或0
另外。