我不理解的东西正在我的两台电脑上发生。我想知道为什么会这样:
如果我输入:
x<-seq(0,20,.05)
x[30]
x[30]==1.45
有人有一个线索,为什么我从最后一行代码中获得一个False?我的另一台计算机上也发生了同样的事情。我在这做错了什么?
感谢您的帮助
答案 0 :(得分:5)
这个问题已被问过一百万次,虽然形式各异。这是由于floating point inaccuracy。还有here's another link关于浮点错误的问题,你可能想要了解它!
试试这个,先看看发生了什么:
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位左右。因此,通过直接比较结果,您当然会得到一个错误。相反,您可以使用all.equal
,其中容差的参数等于.Machine$double.eps ^ 0.5
。在我的机器上,这评估为1.490116e-08
。这意味着如果数字x[30]
和1.45...
之间的绝对差异是&lt;此阈值,然后all.equal
将此评估为TRUE。
all.equal(x[30], 1.45)
[1] TRUE
另一种方法是明确检查特定的阈值(正如@ eddi的答案所示)。希望这会有所帮助。
答案 1 :(得分:3)
这与double
的这些事实有关,并且在任何语言中比较double
的正确方法都是像:
abs(x[30] - 1.45) < 1e-8 # or whatever precision you think is appropriate