What is the difference between using std::random_device with pRNG e.g. std::mt19937 and without?

1.9k views Asked by At

In C++11 one can generate numbers with the use of std::random_device with or without a pseudo random number generator like mt19937.

What will be the difference using this in this exemplar code:

#include <random>
#include <iostream>

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

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

There are 2 answers

0
Columbo On BEST ANSWER

std::random_device is supposed to get you a seed for engines like mt19937. The quality of successive numbers produced is completely undefined and may easily be insufficient for practical purposes (such as cryptography), so relying on that is out of question.

Apart from that, mt19937 will give you the same sequence when given the same seed. A random_devices values can be only influenced by the string given to its constructor... which implies implementation-defined behavior.

8
Barry On

There are two differences that I know of:

  1. Using mt199937 will be faster but less cryptographically secure.
  2. std::random_device will always be random, but if you initialize your mt19937 with a constant seed it will always give you the same random numbers:

    std::mt19937 mt(2014);

Will give the same sequence of random bits every time. This can be useful if you want to test a specific behavior over and over again. The standard requires this in 26.5.5/4:

Required behavior: The 10000th consecutive invocation of a default-constructed object of type mt19937 shall produce the value 4123659995.

There is no such equivalent consistency with std::random_device.