Ernest A
Ernest A

Reputation: 7839

how to avoid NaNs due to rounding errors

Consider the calculation

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

when x=sqrt(5). The sqrt argument becomes negative due to a rounding error and the result of the whole expression is 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

The correct result is

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

Upvotes: 4

Views: 6456

Answers (1)

josliber
josliber

Reputation: 44330

If you don't want the square root to return NaN values, one option is to just use pmax to make sure its argument is at least 0:

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

If you wanted it to return NaN when the argument to sqrt is quite negative but 0 when it's really close to 0 but negative, then ifelse could help:

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

Upvotes: 6

Related Questions