Je remplirais à l'avance un tampon (circulaire) (suffisamment long) de valeurs aléatoires de 64 bits, puis je prendrais très rapidement un bit à la fois lorsque j'aurais besoin d'une valeur aléatoire booléenne.
#include <stdint.h>
class BoolGenerator {
private:
const int BUFFER_SIZE = 65536;
uint64_t randomBuffer[BUFFER_SIZE];
uint64_t mask;
int counter;
void advanceCounter {
counter++;
if (counter == BUFFER_SIZE) {
counter = 0;
}
}
public:
BoolGenerator() {
//HERE FILL YOUR BUFFER WITH A RANDOM GENERATOR
mask = 1;
counter = 0;
}
bool generate() {
mask <<= 1;
if (!mask) { //After 64 shifts the mask becomes zero
mask = 1;//reset mask
advanceCounter();//get the next value in the buffer
}
return randomBuffer[counter] & mask;
}
}
Bien entendu, la classe peut être généralisée à la taille du tampon, au générateur aléatoire, au type de base (qui ne doit pas nécessairement être uint64_t), etc.
Accès au tampon une seule fois tous les 64 appels :
#include <stdint.h> //...and much more
class BoolGenerator {
private:
static const int BUFFER_SIZE = 65536;
uint64_t randomBuffer[BUFFER_SIZE];
uint64_t currValue;
int bufferCounter;
int bitCounter;
void advanceBufferCounter() {
bufferCounter++;
if (bufferCounter == BUFFER_SIZE) {
bufferCounter = 0;
}
}
void getNextValue() {
currValue = randomBuffer[bufferCounter];
bitCounter = sizeof(uint64_t) * 8;
advanceBufferCounter();
}
//HERE FILL YOUR BUFFER WITH A RANDOM GENERATOR
void initializeBuffer() {
//Anything will do, taken from here: http://stackoverflow.com/a/19728404/2436175
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<uint64_t> uni(0,std::numeric_limits<uint64_t>::max());
for (int i = 0; i < BUFFER_SIZE; i++ ) {
randomBuffer[i] = uni(rng);
}
}
public:
BoolGenerator() {
initializeBuffer();
bufferCounter = 0;
getNextValue();
}
bool generate() {
if (!bitCounter) {
getNextValue();
}
//A variation of other methods seen around
bitCounter--;
bool retVal = currValue & 0x01;
currValue >>= 1;
return retVal;
}
};