generate random number in c++

早过忘川 提交于 2019-12-02 00:41:06

From here, you can see std::random_device does not always guarantee to be non-deterministic:

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 each std::random_device object may generate the same number sequence.

On Linux, it by default uses /dev/urandom or RDRND CPU instruction according to here:

The implementations in libc++ and libstdc++ expect token to be the name of a character device that produces random numbers when read from, with the default value "/dev/urandom", although where the CPU instruction RDRND is available, libstdc++ uses that as the default.

which won't block. You can switch to a even secured device /dev/random using approach here, but that device will block if not having enough entropy.

On Windows, I'm not sure about such device therefore it might fall back to some PRNG which requires some kind of seed.

To solve the problem cross-platformly, as @Binara mentioned, you can use std::rand from <cstdlib>. This function will not block, and you can use std::srand(somethingLikeCurrentTime) to make it some-what non-deterministic.

As @user1118321 mentioned, if you want to use a more secured PRNG, you might consider std::mersenne_twister_engine and use std::random_device to generate a seed of it. This approach is suggested here.

Assuming you don't need cryptographically secure random number generation, then you can use the std::mt19937 random generator. It's the Meresenne Twister random generator that has a period of 219937 iterations before it repeats. I've used it like this in the past:

std::array<int, std::mt19937::state_size> seedData;
std::random_device  randDevice;
std::mt19937 eng;
std::uniform_real_distribution<double> randGen(0, 1);
std::generate_n(seedData.data(), seedData.size(), std::ref(randDevice));
std::seed_seq seq(std::begin(seedData), std::end(seedData));
eng.seed(seq);

That creates an array containing the seed of the appropriate size. It creates a random device to set up the seed. Then it creates an mt19937 random generator engine to generate the numbers. To use it to generate values between 0 and 1 you can use the std::uniform_real_distribution like this:

double randVal = randGen(eng);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!