可以说我有如下功能:
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 ...,并且在显示时四舍五入。但这只是一个猜测。究竟如何运作?
这恰好是一个浮点问题,但对我而言,有趣的是它如何证明了的返回值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
由于您无法预测浮点算术的各种实现的行为,因此需要对其进行更正。在这里,使用而不是==
使用dplyr::near()
。在多种语言中都发现了这个问题(浮点数学是不精确的,也是不可预测的)。一种语言中的不同实现将导致不同的浮点错误。
正如我在讨论这个回答另一个浮点问题,dplyr::near()
一样all.equal()
,有一个宽容的说法,在这里tol
。.Machine$double.eps^0.5
默认情况下设置为。.Machine$double.eps
是您的计算机可以添加1
并能够与之区别的最小数字1
。这不是精确的,但是在那个数量级上。取平方根会使它大一点,并允许您准确地确定那些偏离量,这些量会使对相等性的测试失败,很可能是浮点错误。
注意:是的,它near()
是在dplyr中,我几乎一直都在加载它,所以我忘记了它不在基础中……您可以使用all.equal()
,但请查看的源代码near()
。正是您所需要的,而您却不需要:
near
# function (x, y, tol = .Machine$double.eps^0.5)
# {
# abs(x - y) < tol
# }
# <environment: namespace:dplyr>
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句