summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTylo <[email protected]>2020-06-05 17:14:43 +0200
committerTylo <[email protected]>2020-06-05 17:14:43 +0200
commit8f3e91f4f429f834dc815443b7eb1f8883d08d7f (patch)
treecb09a510cf79aa827b56d14836132fe975b56d55
parent364267b39b0f670017d40abc497d85c0b6a4b7bf (diff)
downloadSTC-modified-8f3e91f4f429f834dc815443b7eb1f8883d08d7f.tar.gz
STC-modified-8f3e91f4f429f834dc815443b7eb1f8883d08d7f.zip
Added xoroshiro128ss_jump, sfc32, and fast convertion to float/double.
-rw-r--r--stc/crandom.h57
1 files changed, 55 insertions, 2 deletions
diff --git a/stc/crandom.h b/stc/crandom.h
index 5ff6cad4..b886ff17 100644
--- a/stc/crandom.h
+++ b/stc/crandom.h
@@ -108,6 +108,45 @@ STC_API uint64_t xoroshiro128ss_rand(xoroshiro128ss_t *state) {
return result;
}
+STC_API void xoroshiro128ss_jump(xoroshiro128ss_t *state, bool longJump) {
+ static const uint64_t JUMP2_64[] = {0xdf900294d8f554a5, 0x170865df4b3201fc},
+ JUMP2_96[] = {0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1};
+ const uint64_t *jump = longJump ? JUMP2_96 : JUMP2_64;
+ uint64_t s0 = 0, s1 = 0, *s = state->s;
+
+ for (int i = 0; i < 2; ++i) for (int b = 0; b < 64; ++b) {
+ if (jump[i] & (1ull << b)) s0 ^= s[0], s1 ^= s[1];
+ xoroshiro128ss_rand(state);
+ }
+ s[0] = s0;
+ s[1] = s1;
+}
+
+/*
+ * sfc32: http://pracrand.sourceforge.net
+ */
+
+typedef struct sfc32 {
+ uint32_t s[3], counter;
+} sfc32_t;
+
+STC_API uint32_t sfc32_rand(sfc32_t* state) {
+ enum {LROT = 21, RSHIFT = 9, LSHIFT = 3};
+ uint32_t *s = state->s;
+
+ uint32_t result = s[0] + s[1] + state->counter++;
+ s[0] = s[1] ^ (s[1] >> RSHIFT);
+ s[1] = s[2] + (s[2] << LSHIFT);
+ s[2] = ((s[2] << LROT) | (s[2] >> (32 - LROT))) + result;
+ return result;
+}
+
+STC_API sfc32_t sfc32_seed(const uint64_t seed) {
+ sfc32_t state = {{0, (uint32_t) seed, (uint32_t) (seed >> 32)}, 1};
+ for (int i = 0; i < 12; ++i) sfc32_rand(&state);
+ return state;
+}
+
/*
* sfc64: http://pracrand.sourceforge.net
*/
@@ -120,7 +159,7 @@ STC_API uint64_t sfc64_rand(sfc64_t* state) {
enum {LROT = 24, RSHIFT = 11, LSHIFT = 3};
uint64_t *s = state->s;
- uint64_t result = s[0] + s[1] + ++state->counter;
+ uint64_t result = s[0] + s[1] + state->counter++;
s[0] = s[1] ^ (s[1] >> RSHIFT);
s[1] = s[2] + (s[2] << LSHIFT);
s[2] = c_rotateLeft64(s[2], LROT) + result;
@@ -128,12 +167,26 @@ STC_API uint64_t sfc64_rand(sfc64_t* state) {
}
STC_API sfc64_t sfc64_seed(const uint64_t seed) {
- sfc64_t state = {{seed, seed, seed}, 0};
+ sfc64_t state = {{seed, seed, seed}, 1};
for (int i = 0; i < 12; ++i) sfc64_rand(&state);
return state;
}
/*
+ * convert random int number to float in [0, 1) range.
+ */
+
+STC_API float rand_toFloat(uint32_t rnd) {
+ union {uint32_t i; float f;} v = {0x3F800000u | (rnd >> 9)};
+ return v.f - 1.0f;
+}
+
+STC_API double rand_toDouble(uint64_t rnd) {
+ union {uint64_t i; double f;} v = {0x3FF0000000000000ull | (rnd >> 12)};
+ return v.f - 1.0;
+}
+
+/*
* siphash implementation.
*/