1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
#ifndef RANDOM_GEN_H_
#define RANDOM_GEN_H_
#include "assert_helpers.h"
/**
* Simple pseudo-random linear congruential generator, a la Numerical
* Recipes.
*/
class RandomSource {
public:
static const uint32_t DEFUALT_A = 1664525;
static const uint32_t DEFUALT_C = 1013904223;
RandomSource() :
a(DEFUALT_A), c(DEFUALT_C), inited_(false) { }
RandomSource(uint32_t _a, uint32_t _c) :
a(_a), c(_c), inited_(false) { }
void init(uint32_t seed = 0) {
last = seed;
inited_ = true;
}
uint32_t nextU32() {
assert(inited_);
uint32_t ret;
last = a * last + c;
ret = last >> 16;
last = a * last + c;
ret ^= last;
lastOff = 0;
return ret;
}
uint64_t nextU64() {
assert(inited_);
uint64_t first = nextU32();
first = first << 32;
uint64_t second = nextU32();
return first | second;
}
size_t nextSizeT() {
if(sizeof(size_t) == 4) {
return nextU32();
} else {
return nextU64();
}
}
template <typename T>
T nextU() {
if(sizeof(T)>4)
return nextU64();
return nextU32();
}
uint32_t nextU2() {
assert(inited_);
if(lastOff > 30) {
nextU32();
}
uint32_t ret = (last >> lastOff) & 3;
lastOff += 2;
return ret;
}
static uint32_t nextU32(uint32_t last,
uint32_t a = DEFUALT_A,
uint32_t c = DEFUALT_C)
{
return (a * last) + c;
}
private:
uint32_t a;
uint32_t c;
uint32_t last;
uint32_t lastOff;
bool inited_;
};
#endif /*RANDOM_GEN_H_*/
|