Add xorshift prng
This commit is contained in:
parent
70e075d2f6
commit
d661312cfa
6
src/prng/wapp_prng.c
Normal file
6
src/prng/wapp_prng.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef WAPP_PRNG_C
|
||||||
|
#define WAPP_PRNG_C
|
||||||
|
|
||||||
|
#include "xorshift/xorshift.c"
|
||||||
|
|
||||||
|
#endif // !WAPP_PRNG_C
|
7
src/prng/wapp_prng.h
Normal file
7
src/prng/wapp_prng.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef WAPP_PRNG_H
|
||||||
|
#define WAPP_PRNG_H
|
||||||
|
|
||||||
|
#include "xorshift/xorshift.h"
|
||||||
|
#include "../common/wapp_common.h"
|
||||||
|
|
||||||
|
#endif // !WAPP_PRNG_H
|
89
src/prng/xorshift/xorshift.c
Normal file
89
src/prng/xorshift/xorshift.c
Normal 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);
|
||||||
|
}
|
27
src/prng/xorshift/xorshift.h
Normal file
27
src/prng/xorshift/xorshift.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef XORSHIFT_H
|
||||||
|
#define XORSHIFT_H
|
||||||
|
|
||||||
|
#include "../../common/aliases/aliases.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
BEGIN_C_LINKAGE
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
typedef struct xor_256_state XOR256State;
|
||||||
|
struct xor_256_state {
|
||||||
|
u64 x;
|
||||||
|
u64 y;
|
||||||
|
u64 z;
|
||||||
|
u64 w;
|
||||||
|
};
|
||||||
|
|
||||||
|
XOR256State wapp_init_xor_256_state(void);
|
||||||
|
u64 wapp_xorshift_256_generate(XOR256State *state);
|
||||||
|
u64 wapp_xoshiro_256ss_generate(XOR256State *state);
|
||||||
|
u64 wapp_xoshiro_256p_generate(XOR256State *state);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
END_C_LINKAGE
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif // !XORSHIFT_H
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "wapp.h"
|
#include "wapp.h"
|
||||||
#include "core/wapp_core.c"
|
#include "core/wapp_core.c"
|
||||||
|
#include "prng/wapp_prng.c"
|
||||||
#include "testing/wapp_testing.c"
|
#include "testing/wapp_testing.c"
|
||||||
|
|
||||||
#endif // !WAPP_C
|
#endif // !WAPP_C
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "common/wapp_common.h"
|
#include "common/wapp_common.h"
|
||||||
#include "core/wapp_core.h"
|
#include "core/wapp_core.h"
|
||||||
|
#include "prng/wapp_prng.h"
|
||||||
#include "testing/wapp_testing.h"
|
#include "testing/wapp_testing.h"
|
||||||
|
|
||||||
#endif // !WAPP_H
|
#endif // !WAPP_H
|
||||||
|
Loading…
Reference in New Issue
Block a user