为什么在is.wholenumber中使用此容差

Erw*_*gen 7 r

帮助页面?is.integer有一个关于函数的注释,它将告诉我们一个值是否为整数:

is.wholenumber <-
   function(x, tol = .Machine$double.eps^0.5)  abs(x - round(x)) < tol
Run Code Online (Sandbox Code Playgroud)

sqrt(eps)在这里用作容忍的理由是什么?还有,有充分的理由使用其他东西tol=0吗?

背景是我对这个问题的回答.一些评论者反对这一功能.

我的简单假设:这样做是为了使其在行为中接近打印(默认值为7位十进制数).例如:

> 1.000005
[1] 1.000005
> 1.0000000005
[1] 1
> is.wholenumber(1.000005)
[1] FALSE
> is.wholenumber(1.0000000005)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

但它并不完美:

> 1.00000005
[1] 1
> is.wholenumber(1.00000005)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

在下面的注释中有一个更好的论据:sqrt(eps)可能是由浮点运算引起的舍入误差的(粗略)估计.

A. *_*ebb 2

比较

\n\n
> is.wholenumber(0.6/0.2, tol=0)\n[1] FALSE\n> is.wholenumber(0.6/0.2)\n[1] TRUE\n
Run Code Online (Sandbox Code Playgroud)\n\n

虽然3 == 0.6/0.3在现实中确实如此,但在浮点表示中却并非如此。

\n\n

从帮助文件中"=="

\n\n
\n

对于数值和复数值,请记住 \xe2\x80\x98==\xe2\x80\x99 和 \xe2\x80\x98!=\xe2\x80\x99 不允许分数的有限表示,也不允许舍入\n错误。使用 \xe2\x80\x98all.equal\xe2\x80\x99 和 \xe2\x80\x98identical\xe2\x80\x99 几乎总是更好。

\n
\n\n

的默认容差is.wholenumber设置为与以下相同的量all.equal

\n\n
 ## S3 method for class \'numeric\'\n all.equal(target, current,\n           tolerance = .Machine$double.eps ^ 0.5, scale = NULL,\n           ..., check.attributes = TRUE)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这意味着 的默认行为is.wholenumber相当于

\n\n
isTRUE(all.equal(0,abs(x - round(x))))\n
Run Code Online (Sandbox Code Playgroud)\n\n

以我们的例子为例

\n\n
> x <- 0.6/0.2\n> x\n[1] 3\n> round(x)\n[1] 3\n> x == round(x)\n[1] FALSE\n> isTRUE(all.equal(0,x-round(x)))\n[1] TRUE\n> isTRUE(all.equal(0,x-round(x), tol=0))\n[1] FALSE\n
Run Code Online (Sandbox Code Playgroud)\n