Reputation: 6805
Background:
Since c++11, it is recommended to use a std::random_device
instead of the time to seed a random number generator. If we take a look at the related documentation, we can read that:
std::random_device
may be implemented in terms of an implementation-defined pseudo-random number engine if a non-deterministic source (e.g. a hardware device) is not available to the implementation. In this case eachstd::random_device
object may generate the same number sequence.
emphasis mine
Let's now consider the following example:
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution distr(0, 9);
// Print a sequence of 10 uniformly distributed random integers
for(std::size_t i = 0; i < 10; ++i)
std::cout << distr(gen) << ' ';
return 0;
}
If the system/platform does not provide a non-deterministic source, this program may/will always generate the same sequence of numbers for each run (it is actually the case on my platform).
In this case, std::random_device
is far worse than seeding the random number generator with the current time:
std::mt199937 gen(std::chrono::high_resolution_clock::now().time_since_epoch().count()); // time seed
Issue:
My concern is that if someone wants to write a program that will rely on some random generated numbers and is required:
Then std::random_device
will not be a right fit.
On the other hand, using always a time seed would be a quite frustrating "solution" since if the given platform has a non-deterministic source available, std::random_device
would then be "safer".
Question:
My question is divided in two parts:
std::random_device
seeds by time seeds if the host platform has no non-deterministic source available ? Or is there something in the standard that would prevent such a replacement?Perhaps these should be 2 or 3 separate questions. Since the background and issue are common, I've asked them in the same post for completeness purposes on the topic. Please let me know if I have to split them into separate questions anyway.
Upvotes: 5
Views: 2219
Reputation: 180500
Is there a portable way to check if such a non-deterministic source is available on the current platform?
You can use the entropy
member function of std::random_device
to check if the source is non-deterministic or not. Unfortunately it is not a static constexpr
function so you'll have to use a regular if statement like
int main()
{
std::random_device rd;
std::size_t seed;
if (rd.entropy())
seed = rd();
else
seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::mt19937 gen(seed);
std::uniform_int_distribution distr(0, 9);
// Print a sequence of 10 uniformly distributed random integers
for(std::size_t i = 0; i < 10; ++i)
std::cout << distr(gen) << ' ';
return 0;
}
Are compilers allowed to replace
std::random_device
seeds by time seeds if the host platform has no non-deterministic source available ? Or is there something in the standard that would prevent such a replacement?
That would change the observable behavior of the program so no, the compiler can't do that.
Upvotes: 3