42 lines
985 B
C
42 lines
985 B
C
#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);
|
|
}
|