如何避免由于舍入错误导致的NaN

时间:2015-05-15 19:08:08

标签: r floating-accuracy

考虑计算

x * -3/10 + sqrt(1/20 - x^2 / 100)

x=sqrt(5)时。由于舍入错误,sqrt参数变为负数,整个表达式的结果为NaN

> x <- sqrt(5)
> x * -3/10 + sqrt(1/20 - x^2 / 100)
[1] NaN
Warning message:
In sqrt(1/20 - sqrt(5)^2/100) : NaNs produced

正确的结果是

> sqrt(5) * -3/10
[1] -0.6708204

1 个答案:

答案 0 :(得分:5)

如果您不希望平方根返回NaN值,则可以选择使用pmax来确保其参数至少为0:

x * -3/10 + sqrt(pmax(0, 1/20 - x^2 / 100))
# [1] -0.6708204

如果您希望它在NaN的参数非常消极时返回sqrt,但在它真正接近0但是为负数时返回0,那么ifelse可能会有所帮助:

x <- sqrt(4:6)
special.sqrt <- function(x) ifelse(x < -1e-10, NaN, sqrt(pmax(0, x)))
x * -3/10 + special.sqrt(1/20 - x^2 / 100)
# [1] -0.5000000 -0.6708204        NaN