summaryrefslogtreecommitdiff
path: root/source/kit/mersenne_twister_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/kit/mersenne_twister_64.c')
-rw-r--r--source/kit/mersenne_twister_64.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/source/kit/mersenne_twister_64.c b/source/kit/mersenne_twister_64.c
new file mode 100644
index 0000000..4be4313
--- /dev/null
+++ b/source/kit/mersenne_twister_64.c
@@ -0,0 +1,62 @@
+#include "mersenne_twister_64.h"
+
+#include <time.h>
+
+void kit_mt64_init(kit_mt64_state_t *state, uint64_t seed) {
+ state->mt[0] = seed;
+ for (state->index = 1; state->index < KIT_MT64_N; state->index++)
+ state->mt[state->index] = (6364136223846793005ull *
+ (state->mt[state->index - 1] ^
+ (state->mt[state->index - 1] >>
+ 62u)) +
+ state->index);
+}
+
+uint64_t kit_mt64_generate(kit_mt64_state_t *state) {
+ static uint64_t const mag01[2] = { 0ull, 0xB5026F5AA96619E9ull };
+
+ int i;
+ uint64_t x;
+
+ if (state->index >= KIT_MT64_N) {
+ for (i = 0; i < KIT_MT64_N - 156; i++) {
+ x = (state->mt[i] & 0xFFFFFFFF80000000ull) |
+ (state->mt[i + 1] & 0x7FFFFFFFull);
+ state->mt[i] = state->mt[i + 156] ^ (x >> 1u) ^
+ mag01[(int) (x & 1ull)];
+ }
+
+ for (; i < KIT_MT64_N - 1; i++) {
+ x = (state->mt[i] & 0xFFFFFFFF80000000ull) |
+ (state->mt[i + 1] & 0x7FFFFFFFull);
+ state->mt[i] = state->mt[i + (156 - KIT_MT64_N)] ^ (x >> 1u) ^
+ mag01[(int) (x & 1ull)];
+ }
+
+ x = (state->mt[KIT_MT64_N - 1] & 0xFFFFFFFF80000000ull) |
+ (state->mt[0] & 0x7FFFFFFFull);
+ state->mt[KIT_MT64_N - 1] = state->mt[156 - 1] ^ (x >> 1u) ^
+ mag01[(int) (x & 1ull)];
+
+ state->index = 0;
+ }
+
+ x = state->mt[state->index++];
+
+ x ^= (x >> 29u) & 0x5555555555555555ull;
+ x ^= (x << 17u) & 0x71D67FFFEDA60000ull;
+ x ^= (x << 37u) & 0xFFF7EEE000000000ull;
+ x ^= (x >> 43u);
+
+ return x;
+}
+
+uint64_t kit_mt64_seed() {
+ struct timespec t;
+ timespec_get(&t, TIME_UTC);
+
+ kit_mt64_state_t s;
+ kit_mt64_init(&s, (uint64_t) t.tv_nsec);
+
+ return kit_mt64_generate(&s);
+}