#include "kknd.h" /* xoroshiro128** deterministic RNG */ void rng_seed(RNG *r, uint64_t seed) { if (seed == 0) seed = 0x9E3779B97F4A7C15ULL; r->s[0] = seed; r->s[1] = seed ^ 0xBF58476D1CE4E5B9ULL; if (r->s[0] == 0) r->s[0] = 1; if (r->s[1] == 0) r->s[1] = 2; } static inline uint64_t rotl(uint64_t x, int k) { return (x << k) | (x >> (64 - k)); } uint64_t rng_u64(RNG *r) { uint64_t s0 = r->s[0]; uint64_t s1 = r->s[1]; uint64_t result = rotl(s0 * 5, 7) * 9; s1 ^= s0; r->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); r->s[1] = rotl(s1, 37); return result; } uint32_t rng_u32(RNG *r) { return (uint32_t)(rng_u64(r) >> 32); } int rng_range(RNG *r, int lo, int hi) { if (hi <= lo) return lo; return lo + (int)(rng_u32(r) % (uint32_t)(hi - lo + 1)); } float rng_f32(RNG *r) { return (float)(rng_u32(r) >> 8) / (float)(1 << 24); } float rng_frange(RNG *r, float lo, float hi) { return lo + rng_f32(r) * (hi - lo); }