如果我输入:
x<-seq(0,20,.05)
x[30]
x[30]==1.45
为什么我False
从最后一行代码中获得一个?我在这里做错了什么?
这个问题已经被问过一百万次了,尽管形式不同。这是由于浮点数不准确造成的。这里还有另一个关于浮点错误的链接,您可能想了解一下!
试试这个首先看看发生了什么:
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.equal
which 有一个公差参数等于.Machine$double.eps ^ 0.5
。在我的机器上,这评估为1.490116e-08
. 这意味着如果数字x[30]
和之间的绝对差小1.45...
于此阈值,则将其all.equal
评估为 TRUE。
all.equal(x[30], 1.45)
[1] TRUE
另一种方法是明确检查特定阈值(如@eddi 的回答所示)。
这与这些是 's 的事实有关,并且在任何语言double
中比较 's 的正确方法是执行以下操作:double
abs(x[30] - 1.45) < 1e-8 # or whatever precision you think is appropriate