#include #include /* This code uses Xorshift (high speed, small) and PCG (Permuted Congruential Generator). PCG may or may not be slightly slower than Xorshift. */ static uint32_t xorshift_state = 2463534242; static void srand_xorshift(uint32_t seed) { xorshift_state = seed; } static inline uint32_t rand_xorshift(void) { uint32_t x = xorshift_state; x ^= x << 13; x ^= x >> 17; x ^= x << 5; return xorshift_state = x; } static uint64_t state = 0x853c49e6748fea9bULL; static uint64_t inc = 0xda3e39cb94b95bdbULL; static inline uint32_t rand_pcg32(void) { uint64_t oldstate = state; state = oldstate * 6364136223846793005ULL + (inc | 1); uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; uint32_t rot = oldstate >> 59u; return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); } void seed_rand(uint32_t seed) { srand_xorshift(seed); state = seed * 6364136223846793005ULL + (seed | 1); } uint32_t uirand(void) { return rand_pcg32() ^ rand_xorshift(); } /* get a number between 0 and max-1 */ uint32_t uirand_range(uint32_t max) { if (max == 0) { return 0; } return uirand() % max; } uint64_t ulrand(void) { uint64_t hi = uirand(); uint64_t lo = uirand(); return (hi << 32) | lo; } /* get a number between 0 and max-1 */ uint64_t ulrand_range(uint64_t max) { if (max == 0) { return 0; } return ulrand() % max; }