Add xorshift prng

This commit is contained in:
Abdelrahman Said
2025-03-16 22:34:56 +00:00
parent 70e075d2f6
commit d661312cfa
6 changed files with 131 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
#include "xorshift.h"
#include "../../common/aliases/aliases.h"
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
typedef struct split_mix_64_state SplitMix64State;
struct split_mix_64_state {
u64 seed;
};
internal u64 rol64(u64 x, u64 bits);
internal u64 split_mix_64(SplitMix64State *state);
XOR256State wapp_init_xor_256_state(void) {
persistent bool seeded = false;
if (!seeded) {
seeded = true;
struct timespec ts = {0};
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
srand48(ts.tv_nsec);
}
SplitMix64State sm64 = {.seed = lrand48()};
return (XOR256State){
.x = split_mix_64(&sm64),
.y = split_mix_64(&sm64),
.z = split_mix_64(&sm64),
.w = split_mix_64(&sm64),
};
}
u64 wapp_xorshift_256_generate(XOR256State *state) {
u64 t = state->x ^ (state->x << 11);
state->x = state->y;
state->y = state->z;
state->z = state->w;
state->w = (state->w ^ (state->w >> 19)) ^ (t ^ (t >> 8));
return state->w;
}
u64 wapp_xoshiro_256ss_generate(XOR256State *state) {
const u64 result = rol64(state->z * 5, 7) * 9;
const u64 t = state->z << 17;
state->y ^= state->w;
state->x ^= state->z;
state->z ^= state->y;
state->w ^= state->x;
state->y ^= t;
state->x = rol64(state->x, 45);
return result;
}
u64 wapp_xoshiro_256p_generate(XOR256State *state) {
const u64 result = state->w + state->x;
const u64 t = state->z << 17;
state->y ^= state->w;
state->x ^= state->z;
state->z ^= state->y;
state->w ^= state->x;
state->y ^= t;
state->x = rol64(state->x, 45);
return result;
}
internal u64 rol64(u64 x, u64 bits) {
return (x << bits) | (x >> (64 - bits));
}
internal u64 split_mix_64(SplitMix64State *state) {
state->seed += 0x9E3779B97f4A7C15;
u64 result = state->seed;
result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9;
result = (result ^ (result >> 27)) * 0x94D049BB133111EB;
return result ^ (result >> 31);
}