Generate uniform random number in open interval

in C ++, I can't seem to find a way to generate a random number from a uniform distribution in an open interval such as (0,1).

(double)rand()/RAND_MAX;

      

will include 0 and 1? If so, what is the correct way to generate a random number in an open interval? thank

0


source to share


4 answers


I haven't written C ++ in age, but I'll try the following code:



double M = 0.00001, N = 0.99999;
double rNumber = M + rand() / (RAND_MAX / (N - M + 1) + 1);

      

0


source


I haven't programmed in C ++ for a few years now, but when I was doing the rand implementation it was compiler specific. The implementations are different as to whether they cover [0, RAND_MAX], [0, RAND_MAX], (0, RAND_MAX), or (0, RAND_MAX). This could change and I'm sure someone will call if this happens.

Suppose the implementation runs over a closed interval [0, RAND_MAX], then (double)(rand()+1)/(RAND_MAX+2);

should give an open interval U (0,1), unless RAND_MAX

prompted by the word size long. Adjust the additive constants if your generator covers the range differently.



An even better solution would be to cut rand

and use something like the Mersenne Twister from the Boost libraries. MT has various challenges that explicitly give you control over the open / closed range of results.

0


source


Given the even distribution of RNGs with a closed interval [a, b], the easiest way is to simply discard the unwanted values, roll the dice again. This is both numerically stable and virtually the fastest way to maintain uniformity.

 double myRnD()
 {
    double a = 0.0;
    while (a == 0.0 || a == 1.0) a = (double)rand() * (1.0 / (double)RAND_MAX);
    return a;
 }

      

(Disclaimer: RAND_MAX must be a power of two and <2 ^ 52)

0


source


Take a look at std :: uniform_real_distribution ! You can use a more professional pseudo-random number generator than bulit-in <cstdlib>

called std :: rand (). Here's a sample code that prints 10 random numbers in the range [0,1]:

#include <iostream>
#include <random>

int main()
{  
    std::default_random_engine generator;
    std::uniform_real_distribution<double> distribution(0.0,1.0);

    for (int i=0; i<10; ++i)
        std::cout << distribution(generator) << endl;

    return 0; 
}

      

It is very unlikely to get exactly zero. If it is very important for you not to receive 0, you can check it and generate another number.

And, of course, you can use the engine specified number as std::mt19937

( "very" casual) or one of the fastest std::knuth_b

.

0


source







All Articles