94 lines
2.3 KiB
C
94 lines
2.3 KiB
C
// vim:fileencoding=utf-8:foldmethod=marker
|
|
|
|
#include "xorshift.h"
|
|
#include "../splitmix64/splitmix64.h"
|
|
#include "../../common/aliases/aliases.h"
|
|
#include "../../common/misc/misc_utils.h"
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
WpXor256State wpPrngXorshiftInit(void) {
|
|
return wpPrngXorshiftInitWithSeed(0);
|
|
}
|
|
|
|
WpXor256State wpPrngXorshiftInitWithSeed(u64 seed) {
|
|
WpSplitmix64State sm64;
|
|
if (seed > 0) {
|
|
sm64 = wpPrngSplitmix64InitWithSeed(seed);
|
|
} else {
|
|
sm64 = wpPrngSplitmix64Init();
|
|
}
|
|
|
|
return (WpXor256State){
|
|
.x = wpPrngSplitmix64(&sm64),
|
|
.y = wpPrngSplitmix64(&sm64),
|
|
.z = wpPrngSplitmix64(&sm64),
|
|
.w = wpPrngSplitmix64(&sm64),
|
|
};
|
|
}
|
|
|
|
u64 wpPrngXorshift256(WpXor256State *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 wpPrngXorshift256ss(WpXor256State *state) {
|
|
const u64 result = wpMiscUtilsRotl64(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 = wpMiscUtilsRotl64(state->x, 45);
|
|
|
|
return result;
|
|
}
|
|
|
|
u64 wpPrngXorshift256p(WpXor256State *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 = wpMiscUtilsRotl64(state->x, 45);
|
|
|
|
return result;
|
|
}
|
|
|
|
u64 wpPrngXorshift256InRange(WpXor256State *state, u64 start, u64 end) {
|
|
return wpPrngXorshift256(state) % (end - start) + start;
|
|
}
|
|
|
|
u64 wpPrngXorshift256ssInRange(WpXor256State *state, u64 start, u64 end) {
|
|
return wpPrngXorshift256ss(state) % (end - start) + start;
|
|
}
|
|
|
|
u64 wpPrngXorshift256pInRange(WpXor256State *state, u64 start, u64 end) {
|
|
return wpPrngXorshift256p(state) % (end - start) + start;
|
|
}
|
|
|
|
u64 wpPrngXorshift256Choice(WpXor256State *state, u64 available_choices) {
|
|
return wpPrngXorshift256(state) % available_choices;
|
|
}
|
|
|
|
u64 wpPrngXorshift256ssChoice(WpXor256State *state, u64 available_choices) {
|
|
return wpPrngXorshift256ss(state) % available_choices;
|
|
}
|
|
|
|
u64 wpPrngXorshift256pChoice(WpXor256State *state, u64 available_choices) {
|
|
return wpPrngXorshift256p(state) % available_choices;
|
|
}
|