让我们说我有如下函数:
testFunction <- function(testInputs){
print( sum(testInputs)+1 == 2 )
return( sum(testInputs) == 1 )
}
当我在命令行上使用以下输入测试:c(0.65,0.3,0.05)时,它会打印并按预期返回TRUE。
然而,当我使用c(1-0.3-0.05,0.3,0.05)时,我得到TRUE打印并返回FALSE。这没有任何意义,因为它意味着sum(testInputs)+1为2但sum(testInputs)不是1.
这就是我的想法:不知何故,印刷值不是1,但可能是0.9999999 ......,并在显示屏上进行了四舍五入。但这只是猜测。这是如何工作的?
答案 0 :(得分:1)
这完全是一个浮点问题,但对我而言有趣的是它如何证明<button class="toggle_menu">
<i class="far fa-circle"></i>
</button>
的返回值会产生此错误,但是sum()
你得不到它
在评论中查看有关浮点数学的链接。以下是如何处理它:
+
对我而言,引人入胜的是:
sum(1-0.3-0.5, 0.3, 0.05) == 1
# [1] FALSE
dplyr::near(sum(1-0.3-0.05, 0.3, 0.05), 1)
# [1] TRUE
因为无法预测浮点运算的各种实现将如何表现,所以需要对其进行校正。在此处,使用(1 - 0.3 - 0.05 + 0.3 + 0.05) == 1
# [1] TRUE
而不是==
。跨语言可以找到这个问题(浮点数学是不精确的,也是不可预测的)。语言中的不同实现将导致不同的浮点错误。
正如我在this answer to another floating point question中所讨论的那样,dplyr::near()
与dplyr::near()
一样,具有容差论证,此处为all.equal()
。默认设置为tol
。 .Machine$double.eps^0.5
是您的计算机可以添加到.Machine$double.eps
的最小数字,并且能够将其与1
区分开来。这不是确切的,但它正处于这个数量级。取平方根使它比它大一点,并且允许您准确地识别那些关闭的值,这将导致失败的相等测试可能是浮点错误。
注意:是的,1
在dplyr中,我几乎总是加载,所以我忘了它不在基础...你可以使用near()
,但看看源代码all.equal()
。这正是你所需要的,没有你不需要的东西:
near()