How do you generate a random double uniformly distributed between 0 and 1 from C++?

后端 未结 13 612
暗喜
暗喜 2020-11-28 22:28

How do you generate a random double uniformly distributed between 0 and 1 from C++?

Of course I can think of some answers, but I\'d like to know what the standard pr

13条回答
  •  日久生厌
    2020-11-28 23:21

    In C++11 and C++14 we have much better options with the random header. The presentation rand() Considered Harmful by Stephan T. Lavavej explains why we should eschew the use of rand() in C++ in favor of the random header and N3924: Discouraging rand() in C++14 further reinforces this point.

    The example below is a modified version of the sample code on the cppreference site and uses the std::mersenne_twister_engine engine and the std::uniform_real_distribution which generates numbers in the [0,1) range (see it live):

    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
        std::random_device rd;
    
    
        std::mt19937 e2(rd());
    
        std::uniform_real_distribution<> dist(0, 1);
    
        std::map hist;
        for (int n = 0; n < 10000; ++n) {
            ++hist[std::round(dist(e2))];
        }
    
        for (auto p : hist) {
            std::cout << std::fixed << std::setprecision(1) << std::setw(2)
                      << p.first << ' ' << std::string(p.second/200, '*') << '\n';
        }
    }
    

    output will be similar to the following:

    0 ************************
    1 *************************
    

    Since the post mentioned that speed was important then we should consider the cppreference section that describes the different random number engines (emphasis mine):

    The choice of which engine to use involves a number of tradeoffs*: the **linear congruential engine is moderately fast and has a very small storage requirement for state. The lagged Fibonacci generators are very fast even on processors without advanced arithmetic instruction sets, at the expense of greater state storage and sometimes less desirable spectral characteristics. The Mersenne twister is slower and has greater state storage requirements but with the right parameters has the longest non-repeating sequence with the most desirable spectral characteristics (for a given definition of desirable).

    So if there is a desire for a faster generator perhaps ranlux24_base or ranlux48_base are better choices over mt19937.

    rand()

    If you forced to use rand() then the C FAQ for a guide on How can I generate floating-point random numbers?, gives us an example similar to this for generating an on the interval [0,1):

    #include 
    
    double randZeroToOne()
    {
        return rand() / (RAND_MAX + 1.);
    }
    

    and to generate a random number in the range from [M,N):

    double randMToN(double M, double N)
    {
        return M + (rand() / ( RAND_MAX / (N-M) ) ) ;  
    }
    

提交回复
热议问题