0

How can I get a uniformly distributed random number from the interval [0, 1]?

I am currently using the following code, but it is in C and I would like to know how one does things in C++ instead.

double RND()
{
    return ((double)rand()/RAND_MAX);
}
Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
Jame
  • 3,746
  • 6
  • 52
  • 101
  • 1
    Even though one reads `rand()/RAND_MAX` a lot, it still is not uniform. – Micha Wiedenmann Apr 01 '15 at 07:13
  • 1. What makes you think that wouldn't work for C++? – Mats Petersson Apr 01 '15 at 07:13
  • I want to find a uniform random. I used above code to generate that number. However, it is better if I create a C++ function – Jame Apr 01 '15 at 07:15
  • Use the random number library in C++11. Mersenne twister is a good starting point. – Bathsheba Apr 01 '15 at 07:16
  • This type of baseline function would be left as-is in C++. If you want to convert it to a method, then you are going to need to define a class to hold that function. If you already have a class that needs this method, just change the function statement line so its a member function of your existing class. – cybermike Apr 01 '15 at 07:17
  • Yes, I am using VC11 lib #include. Could you suggest me one way? I only find the uniform integer number example – Jame Apr 01 '15 at 07:19
  • It's all in the docs. But the fact that you want to *include* 1 makes it a little more interesting: the new libraries do allow that though. – Bathsheba Apr 01 '15 at 07:20
  • Check this answer: [http://stackoverflow.com/a/20136256](http://stackoverflow.com/a/20136256) I think you will find it useful – koukouviou Apr 01 '15 at 07:32

2 Answers2

4

This is actually somewhat tricky to do correctly. For integers, the uniform distribution class produces numbers in the range [min...max], but for real numbers, the range is [min ... max). To get [0 .. 1.0], we need to add a small number to the upper end of the range. As it happens, since our number is 1.0, the standard library gives us exactly the correct number to add as the epsilon() for the target type:

std::mt19937_64 gen{ std::random_device()() };
std::uniform_real_distribution<double> dis{
    0.0,
    1.0 + std::numeric_limits<double>::epsilon()
};

epsilon is the smallest number that can be added to 1.0 and produce a result that compares greater than 1.0, so this allows numbers up to (and including) 1.0, but no greater--precisely the requested range.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
2

You could use the <random> library added in C++11. See cplusplus.com for more information on distribution and different RNGs.

std::default_random_engine generator;
std::uniform_real_distribution<double> distribution(0.0,1.0);
double number = distribution(generator);

EDIT: As pointed out by Captain Giraffe, above code will be for the range [0,1) and not [0,1]. Use T.C.'s suggested std::uniform_real_distribution<double> distribution(0.0,std::nextafter(1.0, 2.0)); to get a closed upper bound.

Araex
  • 21
  • 3