Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

random

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 practice is, to have:

  • Good standards compliance
  • Good randomness
  • Good speed

(speed is more important than randomness for my application).

Thanks a lot!

PS: In case that matters, my target platforms are Linux and Windows.

like image 934
static_rtti Avatar asked Aug 27 '09 12:08

static_rtti


People also ask

How do you get a random double 0 1?

In order to generate Random double type numbers in Java, we use the nextDouble() method of the java. util. Random class. This returns the next random double value between 0.0 (inclusive) and 1.0 (exclusive) from the random generator sequence.

How do you generate uniformly distributed random numbers?

The Uniform Random Number block generates uniformly distributed random numbers over an interval that you specify. To generate normally distributed random numbers, use the Random Number block. Both blocks use the Normal (Gaussian) random number generator ( 'v4' : legacy MATLAB® 4.0 generator of the rng function).

How do you generate a random number 0 or 1 in C++?

C++ Random Number Between 0 And 1 We can use srand () and rand () function to generate random numbers between 0 and 1. Note that we have to cast the output of rand () function to the decimal value either float or double.


2 Answers

An old school solution like:

double X=((double)rand()/(double)RAND_MAX); 

Should meet all your criteria (portable, standard and fast). obviously the random number generated has to be seeded the standard procedure is something like:

srand((unsigned)time(NULL)); 
like image 194
Elemental Avatar answered Sep 28 '22 01:09

Elemental


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 <iostream> #include <iomanip> #include <map> #include <random>  int main() {     std::random_device rd;       std::mt19937 e2(rd());      std::uniform_real_distribution<> dist(0, 1);      std::map<int, int> 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 <stdlib.h>  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) ) ) ;   } 
like image 30
Shafik Yaghmour Avatar answered Sep 28 '22 03:09

Shafik Yaghmour