@@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Add `wpU8Const`, `wpU16Const`, `wpU32Const`, `wpU64Const`, `wpI8Const`, `wpI16Const`, `wpI32Const`, and `wpI64Const`
|
||||
- `wpPrngXorshiftInitWithSeed` to allow for user control with PRNG
|
||||
- `wpPrngXorshift256InRange`, `wpPrngXorshift256ssInRange`, `wpPrngXorshift256pInRange`, `wpPrngXorshift256Choice`, `wpPrngXorshift256ssChoice` and `wpPrngXorshift256pChoice` utilities
|
||||
- `WpSplitmix64State`
|
||||
- `wpPrngSplitmix64Init`, `wpPrngSplitmix64InitWithSeed`, `wpPrngSplitmix64`, `wpPrngSplitmix64InRange`, `wpPrngSplitmix64Choice`
|
||||
- `wpStr8Clear`
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
// vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
#include "splitmix64.h"
|
||||
#include "../../common/aliases/aliases.h"
|
||||
#include "../../common/assert/assert.h"
|
||||
#include "../../common/platform/platform.h"
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
wp_intern void seedOsGenerator(u64 seed);
|
||||
wp_intern u64 genRandomNumber(void);
|
||||
|
||||
WpSplitmix64State wpPrngSplitmix64Init(void) {
|
||||
wp_persist b8 seeded = false;
|
||||
if (!seeded) {
|
||||
seeded = true;
|
||||
seedOsGenerator(0);
|
||||
}
|
||||
|
||||
return (WpSplitmix64State){ .seed = genRandomNumber() };
|
||||
}
|
||||
|
||||
WpSplitmix64State wpPrngSplitmix64InitWithSeed(u64 seed) {
|
||||
return (WpSplitmix64State){ .seed = seed };
|
||||
}
|
||||
|
||||
u64 wpPrngSplitmix64(WpSplitmix64State *state) {
|
||||
state->seed += 0x9E3779B97f4A7C15;
|
||||
|
||||
u64 result = state->seed;
|
||||
result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9;
|
||||
result = (result ^ (result >> 27)) * 0x94D049BB133111EB;
|
||||
|
||||
return result ^ (result >> 31);
|
||||
}
|
||||
|
||||
u64 wpPrngSplitmix64InRange(WpSplitmix64State *state, u64 start, u64 end) {
|
||||
return wpPrngSplitmix64(state) % (end - start) + start;
|
||||
}
|
||||
|
||||
u64 wpPrngSplitmix64Choice(WpSplitmix64State *state, u64 available_choices) {
|
||||
return wpPrngSplitmix64(state) % available_choices;
|
||||
}
|
||||
|
||||
#if defined(WP_PLATFORM_C) && WP_PLATFORM_C_VERSION >= WP_PLATFORM_C11_VERSION
|
||||
#ifdef WP_PLATFORM_POSIX
|
||||
wp_intern void seedOsGenerator(u64 seed) {
|
||||
if (seed == 0) {
|
||||
struct timespec ts = {0};
|
||||
int result = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||
wpRuntimeAssert(result == 0, "Invalid seed value");
|
||||
seed = (u64)ts.tv_nsec;
|
||||
}
|
||||
|
||||
srand48(seed);
|
||||
}
|
||||
|
||||
wp_intern u64 genRandomNumber(void) {
|
||||
return lrand48();
|
||||
}
|
||||
#else
|
||||
wp_intern void seedOsGenerator(u64 seed) {
|
||||
if (seed == 0) {
|
||||
struct timespec ts = {0};
|
||||
int result = timespec_get(&ts, TIME_UTC);
|
||||
wpRuntimeAssert(result != 0, "Invalid seed value");
|
||||
seed = (u64)ts.tv_nsec;
|
||||
}
|
||||
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
wp_intern u64 genRandomNumber(void) {
|
||||
i32 n1 = rand();
|
||||
i32 n2 = rand();
|
||||
|
||||
return (((u64)n1) << 32 | (u64)n2);
|
||||
}
|
||||
#endif // !WP_PLATFORM_POSIX
|
||||
#else
|
||||
wp_intern void seedOsGenerator(u64 seed) {
|
||||
if (seed == 0) {
|
||||
time_t result = time(NULL);
|
||||
wpRuntimeAssert(result != (time_t)(-1), "Invalid seed value");
|
||||
seed = (u64)result;
|
||||
}
|
||||
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
wp_intern u64 genRandomNumber(void) {
|
||||
i32 n1 = rand();
|
||||
i32 n2 = rand();
|
||||
|
||||
return (((u64)n1) << 32 | (u64)n2);
|
||||
}
|
||||
#endif // !WP_PLATFORM_C
|
||||
@@ -0,0 +1,18 @@
|
||||
// vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
#ifndef SPLITMIX64_H
|
||||
#define SPLITMIX64_H
|
||||
|
||||
#include "../../common/aliases/aliases.h"
|
||||
|
||||
typedef struct WpSplitmix64State {
|
||||
u64 seed;
|
||||
} WpSplitmix64State;
|
||||
|
||||
WpSplitmix64State wpPrngSplitmix64Init(void);
|
||||
WpSplitmix64State wpPrngSplitmix64InitWithSeed(u64 seed);
|
||||
u64 wpPrngSplitmix64(WpSplitmix64State *state);
|
||||
u64 wpPrngSplitmix64InRange(WpSplitmix64State *state, u64 start, u64 end);
|
||||
u64 wpPrngSplitmix64Choice(WpSplitmix64State *state, u64 available_choices);
|
||||
|
||||
#endif // !SPLITMIX64_H
|
||||
@@ -3,6 +3,7 @@
|
||||
#ifndef WAPP_PRNG_C
|
||||
#define WAPP_PRNG_C
|
||||
|
||||
#include "splitmix64/splitmix64.c"
|
||||
#include "xorshift/xorshift.c"
|
||||
|
||||
#endif // !WAPP_PRNG_C
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#ifndef WAPP_PRNG_H
|
||||
#define WAPP_PRNG_H
|
||||
|
||||
#include "splitmix64/splitmix64.h"
|
||||
#include "xorshift/xorshift.h"
|
||||
#include "../common/wapp_common.h"
|
||||
|
||||
|
||||
@@ -1,40 +1,29 @@
|
||||
// vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
#include "xorshift.h"
|
||||
#include "../splitmix64/splitmix64.h"
|
||||
#include "../../common/aliases/aliases.h"
|
||||
#include "../../common/assert/assert.h"
|
||||
#include "../../common/platform/platform.h"
|
||||
#include "../../common/misc/misc_utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef struct SplitMix64State SplitMix64State;
|
||||
struct SplitMix64State {
|
||||
u64 seed;
|
||||
};
|
||||
|
||||
wp_intern u64 splitMix64(SplitMix64State *state);
|
||||
wp_intern void seedOsGenerator(u64 seed);
|
||||
wp_intern u64 genRandomNumber(void);
|
||||
|
||||
WpXor256State wpPrngXorshiftInit(void) {
|
||||
return wpPrngXorshiftInitWithSeed(0);
|
||||
}
|
||||
|
||||
WpXor256State wpPrngXorshiftInitWithSeed(u64 seed) {
|
||||
wp_persist b8 seeded = false;
|
||||
if (!seeded) {
|
||||
seeded = true;
|
||||
seedOsGenerator(seed);
|
||||
WpSplitmix64State sm64;
|
||||
if (seed > 0) {
|
||||
sm64 = wpPrngSplitmix64InitWithSeed(seed);
|
||||
} else {
|
||||
sm64 = wpPrngSplitmix64Init();
|
||||
}
|
||||
|
||||
SplitMix64State sm64 = {.seed = genRandomNumber()};
|
||||
|
||||
return (WpXor256State){
|
||||
.x = splitMix64(&sm64),
|
||||
.y = splitMix64(&sm64),
|
||||
.z = splitMix64(&sm64),
|
||||
.w = splitMix64(&sm64),
|
||||
.x = wpPrngSplitmix64(&sm64),
|
||||
.y = wpPrngSplitmix64(&sm64),
|
||||
.z = wpPrngSplitmix64(&sm64),
|
||||
.w = wpPrngSplitmix64(&sm64),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -102,67 +91,3 @@ u64 wpPrngXorshift256ssChoice(WpXor256State *state, u64 available_choices) {
|
||||
u64 wpPrngXorshift256pChoice(WpXor256State *state, u64 available_choices) {
|
||||
return wpPrngXorshift256p(state) % available_choices;
|
||||
}
|
||||
|
||||
wp_intern u64 splitMix64(SplitMix64State *state) {
|
||||
state->seed += 0x9E3779B97f4A7C15;
|
||||
|
||||
u64 result = state->seed;
|
||||
result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9;
|
||||
result = (result ^ (result >> 27)) * 0x94D049BB133111EB;
|
||||
|
||||
return result ^ (result >> 31);
|
||||
}
|
||||
|
||||
#if defined(WP_PLATFORM_C) && WP_PLATFORM_C_VERSION >= WP_PLATFORM_C11_VERSION
|
||||
#ifdef WP_PLATFORM_POSIX
|
||||
wp_intern void seedOsGenerator(u64 seed) {
|
||||
if (seed == 0) {
|
||||
struct timespec ts = {0};
|
||||
int result = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||
wpRuntimeAssert(result == 0, "Invalid seed value");
|
||||
seed = (u64)ts.tv_nsec;
|
||||
}
|
||||
|
||||
srand48(seed);
|
||||
}
|
||||
|
||||
wp_intern u64 genRandomNumber(void) {
|
||||
return lrand48();
|
||||
}
|
||||
#else
|
||||
wp_intern void seedOsGenerator(u64 seed) {
|
||||
if (seed == 0) {
|
||||
struct timespec ts = {0};
|
||||
int result = timespec_get(&ts, TIME_UTC);
|
||||
wpRuntimeAssert(result != 0, "Invalid seed value");
|
||||
seed = (u64)ts.tv_nsec;
|
||||
}
|
||||
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
wp_intern u64 genRandomNumber(void) {
|
||||
i32 n1 = rand();
|
||||
i32 n2 = rand();
|
||||
|
||||
return (((u64)n1) << 32 | (u64)n2);
|
||||
}
|
||||
#endif // !WP_PLATFORM_POSIX
|
||||
#else
|
||||
wp_intern void seedOsGenerator(u64 seed) {
|
||||
if (seed == 0) {
|
||||
time_t result = time(NULL);
|
||||
wpRuntimeAssert(result != (time_t)(-1), "Invalid seed value");
|
||||
seed = (u64)result;
|
||||
}
|
||||
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
wp_intern u64 genRandomNumber(void) {
|
||||
i32 n1 = rand();
|
||||
i32 n2 = rand();
|
||||
|
||||
return (((u64)n1) << 32 | (u64)n2);
|
||||
}
|
||||
#endif // !WP_PLATFORM_C
|
||||
|
||||
Reference in New Issue
Block a user