Getting high precision values from qnorm in the tail

对着背影说爱祢 提交于 2019-12-05 06:32:29

It turns out (as noted by Spencer Graves in his response to this same question on the R-devel list-serve) that qnorm() does in fact perform as advertised. It's just that, to get highly accurate results in the distribution's upper tail, you'll need to avail yourself of the function's lower.tail argument.

Here's how do that:

options(digits=22)

## For values of p in [0, 0.5], specify lower tail probabilities 
qnorm(p = 1e-10)                      ## x: P(X <= x) == 1e-10
# [1] -6.3613409024040557

## For values of p in (0.5, 1], specify upper tail probabilities
qnorm(p = 1e-10, lower.tail=FALSE)    ## x: P(X > x)  == 1e-10     (correct approach)
# [1] 6.3613409024040557
qnorm(p = 1 - 1e-10)                  ## x: P(X <= x) == 1-(1e-1)  (incorrect approach)
# [1] 6.3613408896974208

The problem is that 1-1e-10 (for example) is subject to floating point rounding errors, such that it isn't really the same distance from 1 (the upper end of the interval) as 1e-10 is from 0 (the lower end of the interval). The underlying problem (it's R-FAQ 7.31!) becomes obvious when put in a more familiar guise:

1 - (1 - 1e-10) == 1e-10
## [1] FALSE

Finally, here's a quick confirmation that qnorm() provides accurate (or at least symmetrical) results out to the values claimed in its help file:

qnorm(1e-314)
## [1] -37.906647423565666
qnorm(1e-314, lower.tail=FALSE)
## [1] 37.906647423565666

## With this failing in just the way (and for just the reason) you'd now expect
qnorm(1-1e-314)
# [1] Inf
1 == (1-1e-314)
# [1] TRUE
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!