#include "Xoshiro.h" #include "Vlogging.h" /* Implements the xoshiro128+ PRNG. */ static uint32_t rotl(const uint32_t x, const int k) { return (x << k) | (x >> (32 - k)); } static uint32_t s[4]; static uint32_t splitmix32(uint32_t* x) { uint32_t z = (*x += 0x9e3779b9UL); z = (z ^ (z >> 15)) * 0xbf58476dUL; z = (z ^ (z >> 13)) * 0x94d049bbUL; return z ^ (z >> 16); } static void seed( const uint32_t s0, const uint32_t s1, const uint32_t s2, const uint32_t s3 ) { s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3; } uint32_t xoshiro_next(void) { const uint32_t result = s[0] + s[3]; const uint32_t t = s[1] << 9; s[2] ^= s[0]; s[3] ^= s[1]; s[1] ^= s[2]; s[0] ^= s[3]; s[2] ^= t; s[3] = rotl(s[3], 11); vlog_debug("Next xoshiro is %u.", result); return result; } void xoshiro_seed(uint32_t s) { vlog_debug("Xoshiro seeded with %u.", s); const uint32_t s0 = splitmix32(&s); const uint32_t s1 = splitmix32(&s); const uint32_t s2 = splitmix32(&s); const uint32_t s3 = splitmix32(&s); seed(s0, s1, s2, s3); } float xoshiro_rand(void) { return ((float) xoshiro_next()) / ((float) UINT32_MAX); }