1

如果我输入:

x<-seq(0,20,.05)
x[30]
x[30]==1.45

为什么我False从最后一行代码中获得一个?我在这里做错了什么?

4

2 回答 2

5

这个问题已经被问过一百万次了,尽管形式不同。这是由于浮点数不准确造成的。这里还有另一个关于浮点错误的链接,您可能想了解一下!

试试这个首先看看发生了什么:

x <- seq(0, 20, 0.5)
sprintf("%.20f", x[30]) # convert value to string with 20 decimal places
# [1] "14.50000000000000000000"
x[30] == 14.5
# [1] TRUE

到目前为止一切都很好。现在,试试这个:

x <- seq(0, 20, 0.05)
sprintf("%.20f", x[30]) # convert value to string with 20 decimal places
# [1] "1.45000000000000017764"
x[30] == 1.45
# [1] FALSE

你可以看到机器只能准确地表示这个数字,直到某些数字。在这里,最多 15 位左右。因此,通过直接比较结果,您当然会得到 FALSE。相反,你可以做的是使用all.equalwhich 有一个公差参数等于.Machine$double.eps ^ 0.5。在我的机器上,这评估为1.490116e-08. 这意味着如果数字x[30] 和之间的绝对差小1.45...于此阈值,则将其all.equal评估为 TRUE。

all.equal(x[30], 1.45)
[1] TRUE

另一种方法是明确检查特定阈值(如@eddi 的回答所示)。

于 2013-05-01T19:34:50.547 回答
3

这与这些是 's 的事实有关,并且在任何语言double中比较 's 的正确方法是执行以下操作:double

abs(x[30] - 1.45) < 1e-8   # or whatever precision you think is appropriate
于 2013-05-01T19:34:35.757 回答