Files
c3c/lib/std/math/random/math.simple_random.c3
2023-07-26 14:01:24 +02:00

39 lines
1.0 KiB
C

module std::math;
def SimpleRandom = distinct ulong;
const long SIMPLE_RANDOM_MULTIPLIER @local = 0x5DEECE66D;
const long SIMPLE_RANDOM_ADDEND @local = 0xB;
const long SIMPLE_RANDOM_MASK @local = (1u64 << 48) - 1;
RandomInterface simple_random_interface = {
.seed_fn = fn (random, seed) => ((SimpleRandom*)random.state).set_seeds(seed),
.next_fn = fn (random, bits) => ((SimpleRandom*)random.state).next(bits)
};
fn Random SimpleRandom.as_random(&random)
{
return { .fns = simple_random_interface, .state = random };
}
fn uint SimpleRandom.next(&r, int bits)
{
ulong nextseed = ((ulong)*r * SIMPLE_RANDOM_MULTIPLIER + SIMPLE_RANDOM_ADDEND) & SIMPLE_RANDOM_MASK;
*r = (SimpleRandom)nextseed;
return (uint)(nextseed >> (48 - bits));
}
fn void SimpleRandom.set_seed(&r, ulong seed)
{
*r = (SimpleRandom)((seed ^ SIMPLE_RANDOM_MULTIPLIER) & SIMPLE_RANDOM_MASK);
}
fn void SimpleRandom.set_seeds(&r, char[] seed)
{
char[8] full;
foreach (i, c : seed)
{
full[i % 8] ^= c;
}
r.set_seed(bitcast(full, ulong));
}