C++ random number generation

This post compares random number generation in “the old days”, and in modern C++.

This is how we used to do it:

#include <cstdlib.h>
srand((unsigned)time(NULL));            // seed the random number generator with current time
int random_number = 200 + rand() % 100; // random number between 200 and 299

This is how it looks in modern C++:

#include <random>
random_device rd;                    // a device that allegedly has access to external entropy, like mouse
default_random_engine engine(rd());  // random number generator based on seed
uniform_int_distribution d(200,299); // uniform distribution between 200 and 299, inclusive
int random_number = d(engine);       // random nunmber between 200 and 299

Good stuff: it looks really fancy and extensible.
Bad stuff:
– I wish the naming were better. In real life an engine is a kind of device, so the differene between “device” and “engine” is confusing.
– The code is longer (duh)
– Using two objects, the distribution and the “engine”, to generate a number is annoying.

One could easily create a single object that combines the distribution and the engine, but why extra work?

template<typename Engine, typename IntegerType>
class uniform_int_generator {
    Engine engine_;
    uniform_int_distribution d_;
public:
    uniform_int_generator( IntegerType min, IntegerType  max, Engine&& engine ) :
        d_(min,max),
        engine_(move(engine)) {
    }

    IntegerType operator()() {
        return d_(engine_);
    }
};

int main() {
    random_device rd;
    uniform_int_generator g(200,299, default_random_engine(rd()));
    for (int i=0; i<10; ++i) {
        cout << g() << endl;
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *