I need to generate random Boolean values on a performance-critical path.
The code which I wrote for this is
std::random_device rd;
std::uniform_int_distribution<> randomizer(0, 1);
const int val randomizer(std::mt19937(rd()));
const bool isDirectionChanged = static_cast<bool>(val);
But do not think that this is the best way to do this as I do not like doing static_cast<bool>
.
On the web I have found a few more solutions
1. std::bernoulli_distribution
2. bool randbool = rand() & 1;
Remember to call srand()
at the beginning.
For the purpose of performance, at a price of less "randomness" than e.g. std::mt19937_64
, you can use Xorshift+ to generate 64-bit numbers and then use the bits of those numbers as pseudo-random booleans.
Quoting the Wikipedia:
This generator is one of the fastest generators passing BigCrush
Details: http://xorshift.di.unimi.it/ . There is a comparison table in the middle of the page, showing that mt19937_64
is 2 times slower and is systematic.
Below is sample code (the real code should wrap it in a class):
#include <cstdint>
#include <random>
using namespace std;
random_device rd;
/* The state must be seeded so that it is not everywhere zero. */
uint64_t s[2] = { (uint64_t(rd()) << 32) ^ (rd()),
(uint64_t(rd()) << 32) ^ (rd()) };
uint64_t curRand;
uint8_t bit = 63;
uint64_t xorshift128plus(void) {
uint64_t x = s[0];
uint64_t const y = s[1];
s[0] = y;
x ^= x << 23; // a
s[1] = x ^ y ^ (x >> 17) ^ (y >> 26); // b, c
return s[1] + y;
}
bool randBool()
{
if(bit >= 63)
{
curRand = xorshift128plus();
bit = 0;
return curRand & 1;
}
else
{
bit++;
return curRand & (1<<bit);
}
}