R中for循环的奇怪行为

R中for循环的奇怪行为,r,R,我已经用R编写了很多年了,一些非常奇怪的事情正在发生,让我发疯 我有一个简单的循环: st=0 for (i in 1:20){ if(st==0.3){print("Test passed")} st=st+0.1 } 不知何故,不知道为什么,条件st==0.3永远不会为真,我可以在循环的每一步打印st,事实上,它在正确的一步变为0.3,但它不会触发条件。我尝试过使用其他值,但似乎效果不错,而不是0.3 现在,这只是我为测试问题而做的一个“验证”示例,最初

我已经用R编写了很多年了,一些非常奇怪的事情正在发生,让我发疯

我有一个简单的循环:

st=0
for (i in 1:20){
    if(st==0.3){print("Test passed")}
    st=st+0.1
}
不知何故,不知道为什么,条件st==0.3永远不会为真,我可以在循环的每一步打印
st
,事实上,它在正确的一步变为0.3,但它不会触发条件。我尝试过使用其他值,但似乎效果不错,而不是0.3

现在,这只是我为测试问题而做的一个“验证”示例,最初的示例发生在另一个循环中,在该循环中,类似的if没有触发更多的值,我检查了变量在相应的步骤中获取这些值,而没有任何结果

我怀疑,我不知道,也许某种内部单精度给出了一个稍微不同的数字,没有显示出来,或者类似的东西

知道会发生什么吗

> st=0
> for (i in 1:20){
+   if(st==0.3){print("Test passed")}
+   st=round(st+0.1, 1)
+ }
[1] "Test passed"

那么这只是数字舍入/精度吗?

这是一个数字舍入错误。如果以全精度打印“st”,它很可能等于0.299999998。这里还有很多其他的问题在讨论这个问题。你可以用相同的(st,0.3)代替
st==0.3
,Nope,@Cettt,实际上是一样的。从根本上说,平等性的浮点测试是不完美的/有缺陷的;它们大部分时间都在工作,但几乎肯定会在某个时候失败。@r2evans谢谢你指出这一点。如果(isTRUE(all.equal(st,0.3))如果你从引擎盖下面看,
all.equal.numeric
使用一个公差(它使用
sqrt(.Machine$double.eps)
),那么效果是一样的。我倾向于在更大的数据集中工作,所以我发现
abs(.-val)<1e-8
比逐个
all.equal
比较要快得多,但这只是我的观点。好吧,尝试过并成功了,与Dave2e和Chris comments一样,但奇怪的是在R中精度问题从未发生过,我已经经历了无数次这样的情况。每个人都会在某个时候被这只狗咬。只是今天轮到你了。自豪地穿上那件T恤!:)多年来,我了解到,几乎每种编程语言中的浮点相等测试都存在根本性缺陷,因为它是一种将浮点数存储在固定位数字节集合中的属性。IEEE-754是最基本的“原则”,最终,人们可以高置信度使用的唯一测试是严格不等式测试。我想很多优秀的程序员都错过了这一点。如果
st
是计算值,则遇到精度问题的可能性更高。四舍五入到适当的级别在大多数情况下都有效。我在其他语言中也看到过这个问题。