R在向前和向后循环中显示不同的结果

时间:2013-03-07 10:12:28

标签: r for-loop floating-point floating-accuracy which

如果我使用for循环向前或向后搜索,我会在搜索数组中的某个元素时得到不同的答案。

示例:提供正确答案的代码

vg   = rep(seq(0.9,1.1,0.01),90)
vals = seq(0.9,1.05,0.01)

for(val in vals){
  idx = c()
  idx = which((vg) %in% (val))
  cat(val,":",length(idx),"\t")
}

本准则给出: 0.9:90 0.91:90 0.92:90 0.93:90 0.94:90 0.95:90 0.96:90 0.97:90 0.98:90 0.99:90 1:90 1.01:90 1.02:90 1.03:90 1.04:90 1.05:90

哪个是正确的。但是如果我使用下面的代码更改上面的vg变量的seq:

vg   = rep(seq(1.1,0.9,-0.01),90)
vals = seq(0.9,1.05,0.01)

for(val in vals){
  idx = c()
  idx = which((vg) %in% (val))
  cat(val,":",length(idx),"\t")
}

我得到如下所示的答案,在搜索0.96,0.97等时显示0个元素数量

0.9:0 0.91:0 0.92:0 0.93:90 0.94:90 0.95:90 0.96:0 0.97:0 0.98:0 0.99:0 1:90 1.01:90 1.02:90 1.03:90 1.04:90 1.05:90

为什么会出现这种差异,因为我们在两个代码中都在搜索完全相同的元素?这是一个R Bug吗?

1 个答案:

答案 0 :(得分:4)

为了扩展Andrie的评论,这个 是一个浮点问题。引用好书,The R Inferno

  

一旦我们越过了Acheron,我们就到了第一个圆圈,这是我们的家   善良的异教徒。这些人生活在对浮点的无知中   神。这些异教徒期待:

.1 == .3 / 3
[1] FALSE  
  

是真的。   善良的异教徒也会期待:

seq(0, 1, by=.1) == .3
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  

只有一个值为真。

在你的例子中,如果我们改为使用整数而不是浮点数,它可以工作:

vg   = rep(seq(90,110,1),90)
vals = seq(90,105,1)

for(val in vals){
  idx = c()
  idx = which((vg) %in% (val))
  cat(val,":",length(idx),"\t")
}

vg   = rep(seq(110,90,-1),90)
vals = seq(90,105,1)

for(val in vals){
  idx = c()
  idx = which((vg) %in% (val))
  cat(val,":",length(idx),"\t")
}
90 : 90         91 : 90         92 : 90         93 : 90         94 : 90         95 : 90         96 : 90  

R inferno是一个非常有趣和信息丰富的阅读。我强烈推荐它。

默认情况下,你也可以通过以下方式看到WYSINWYG:

options(digits=22)
.3/3
[1] 0.09999999999999999167333