Generate random numbers using C++11 random library

smac89 picture smac89 · Oct 29, 2013 · Viewed 138.6k times · Source

As the title suggests, I am trying to figure out a way of generating random numbers using the new C++11 <random> library. I have tried it with this code:

std::default_random_engine generator;
std::uniform_real_distribution<double> uniform_distance(1, 10.001);

The problem with the code I have is that every time I compile and run it, it always generates the same numbers. So my question is what other functions in the random library can accomplish this while being truly random?

For my particular use case, I was trying to get a value within the range [1, 10]

Answer

Bill Lynch picture Bill Lynch · Oct 29, 2013

Stephan T. Lavavej (stl) from Microsoft did a talk at Going Native about how to use the new C++11 random functions and why not to use rand(). In it, he included a slide that basically solves your question. I've copied the code from that slide below.

You can see his full talk here: http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

#include <random>
#include <iostream>

int main() {
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<double> dist(1.0, 10.0);

    for (int i=0; i<16; ++i)
        std::cout << dist(mt) << "\n";
}

We use random_device once to seed the random number generator named mt. random_device() is slower than mt19937, but it does not need to be seeded because it requests random data from your operating system (which will source from various locations, like RdRand for example).


Looking at this question / answer, it appears that uniform_real_distribution returns a number in the range [a, b), where you want [a, b]. To do that, our uniform_real_distibution should actually look like:

std::uniform_real_distribution<double> dist(1, std::nextafter(10, DBL_MAX));