]> git.kaiwu.me - klib.git/commitdiff
Added a version of xoroshiro128+
authorHeng Li <lh3@me.com>
Fri, 31 Aug 2018 09:05:18 +0000 (23:05 -1000)
committerHeng Li <lh3@me.com>
Fri, 31 Aug 2018 09:05:18 +0000 (23:05 -1000)
krng.h [new file with mode: 0644]

diff --git a/krng.h b/krng.h
new file mode 100644 (file)
index 0000000..7423a85
--- /dev/null
+++ b/krng.h
@@ -0,0 +1,54 @@
+#ifndef KRNG_H
+#define KRNG_H
+
+typedef struct {
+       uint64_t s[2];
+} krng_t;
+
+static inline uint64_t kr_splitmix64(uint64_t x)
+{
+       uint64_t z = (x += 0x9E3779B97F4A7C15ULL);
+       z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ULL;
+       z = (z ^ (z >> 27)) * 0x94D049BB133111EBULL;
+       return z ^ (z >> 31);
+}
+
+static inline uint64_t kr_rand_r(krng_t *r)
+{
+       const uint64_t s0 = r->s[0];
+       uint64_t s1 = r->s[1];
+       const uint64_t result = s0 + s1;
+       s1 ^= s0;
+       r->s[0] = (s0 << 55 | s0 >> 9) ^ s1 ^ (s1 << 14);
+       r->s[1] = s0 << 36 | s0 >> 28;
+       return result;
+}
+
+static inline void kr_jump_r(krng_t *r)
+{
+       static const uint64_t JUMP[] = { 0xbeac0467eba5facbULL, 0xd86b048b86aa9922ULL };
+       uint64_t s0 = 0, s1 = 0;
+       int i, b;
+       for (i = 0; i < 2; ++i)
+               for (b = 0; b < 64; b++) {
+                       if (JUMP[i] & 1ULL << b)
+                               s0 ^= r->s[0], s1 ^= r->s[1];
+                       kr_rand_r(r);
+               }
+       r->s[0] = s0, r->s[1] = s1;
+}
+
+static inline void kr_srand_r(krng_t *r, uint64_t seed)
+{
+       r->s[0] = kr_splitmix64(seed);
+       r->s[1] = kr_splitmix64(r->s[0]);
+}
+
+static inline double kr_drand_r(krng_t *r)
+{
+       union { uint64_t i; double d; } u;
+       u.i = 0x3FFULL << 52 | kr_rand_r(r) >> 12;
+       return u.d - 1.0;
+}
+
+#endif