I'm new to R, but the documentation surprised me by stating that runif(n) returns a number in the range 0 to 1 inclusive. I would expect 0 <= runif(n) < 1 -- including 0 and not including 1.
I tested it with n = 100,000,000, and found that it never produced 0 or 1. I realize that the probability of actually hitting specific values in floating point is really small, but still... (There are something like 2^53 values between 0 and 1 in double precision).
So I looked into the source code for R and found in r-source-trunk\src\nmath\runif.c
do
{
u = unif_rand();
} while (u <= 0 || u >= 1);
return a + (b - a) * u;
So by design, despite the documentation, it will never ever return a 0 or 1.
Isn't this a bug?
Or at least a problem with the documentation?
The underlying uniform random number function is defined here and the final outputs use this function:
static double fixup(double x)
{
/* ensure 0 and 1 are never returned */
if(x <= 0.0) return 0.5*i2_32m1;
if((1.0 - x) <= 0.0) return 1.0 - 0.5*i2_32m1;
return x;
}
Despite this, there are comments of the form /* in [0,1) */
for each of the generator's return functions, which I assume is a mistake given the above.
And of course, the code you noticed in runif.c is preceded by:
/* This is true of all builtin generators, but protect against
user-supplied ones */
So the min or max will never be returned except in the cases mentioned by @JesseTweedle, which is not the case when just calling runif()
.
For reference, the magic value i2_32m1
is 1/(2^32-1)
so the minimum value you can get from the default generators is 1/(2^33-2)
which is approximately 1.16e-10
. The maximum value is this amount short of 1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With