Generate uniform random number in open interval

2019-08-31 13:44发布

I cannot find a way to generate random number from uniform distribution in an open interval like (0,1).

(double)rand()/RAND_MAX;

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

标签: c++ random
4条回答
够拽才男人
2楼-- · 2019-08-31 14:26

I haven't written C++ in ages but try the following code:

double M = 0.00001, N = 0.99999;
double rNumber = M + rand() / (RAND_MAX / (N - M + 1) + 1);
查看更多
兄弟一词,经得起流年.
3楼-- · 2019-08-31 14:29

Given uniform distribution of a RNG with closed interval [a, b], the easiest method is to simply discard unwanted values an throw the dice again. This is both numerically stable and practically the fastest method 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 would have to be a power of two and < 2^52)

查看更多
贼婆χ
4楼-- · 2019-08-31 14:33

Take a look at std::uniform_real_distribution! You can use a more professional pseudo random number generator than the bulit-in of <cstdlib> called std::rand(). Here's a code example that print outs 10 random numbers in 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 to not to get 0, you can check for it and generate another number.

And of course you can use random number engine specified, as std::mt19937(that is "very" random) or one of the fastest, the std::knuth_b.

查看更多
仙女界的扛把子
5楼-- · 2019-08-31 14:40

I haven't programmed in C++ for a number of years now, but when I did the implementation of rand was compiler specific. Implementations varied as to whether they covered [0,RAND_MAX], [0,RAND_MAX), (0,RAND_MAX], or (0,RAND_MAX). That may have changed, and I'm sure somebody will chime in if it has.

Assume that the implementation is over the closed interval [0,RAND_MAX], then (double)(rand()+1)/(RAND_MAX+2); should yield an open interval U(0,1) unless RAND_MAX is pushing up against the word size, in which case cast to long. Adjust the additive constants if your generator covers the range differently.

An even better solution would be to ditch rand and use something like the Mersenne Twister from the Boost libraries. MT has different calls which explicitly give you control over the open/closed range of the results.

查看更多
登录 后发表回答