这完全是一个浮点问题,但对我来说有趣的是它如何证明 的返回值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 中,我几乎总是加载它,所以我忘了它不在 base 中……你可以使用all.equal()
,但请查看near()
. 这正是您需要的,没有您不需要的:
near
# function (x, y, tol = .Machine$double.eps^0.5)
# {
# abs(x - y) < tol
# }
# <environment: namespace:dplyr>