1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
/* dedicated RNG for use in generating random folds dir use with SVM */
#include <stdint.h>
#include <time.h>
#include <stddef.h>
static uint64_t smx;
static inline uint64_t splitmix64_next() {
uint64_t z = (smx += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
}
static inline uint64_t xor_rotl (const uint64_t x, int k) {
return (x << k) | (x >> (64 - k));
}
static uint64_t s[4];
static void set_xor_state (uint64_t u)
{
s[0] = smx = u;
s[1] = splitmix64_next();
s[2] = splitmix64_next();
s[3] = splitmix64_next();
}
static uint64_t xor_i64 (void) {
const uint64_t ret = s[0] + s[3];
const uint64_t t = s[1] << 17;
s[2] ^= s[0];
s[3] ^= s[1];
s[1] ^= s[2];
s[0] ^= s[3];
s[2] ^= t;
s[3] = xor_rotl(s[3], 45);
return ret;
}
void svrand_init (uint64_t seed)
{
if (seed > 0) {
set_xor_state(seed);
} else {
#ifdef _WIN32
set_xor_state((uint64_t) _time64(NULL));
#else
set_xor_state((uint64_t) time(NULL));
#endif
}
}
uint32_t svrand (void)
{
return (uint32_t) (xor_i64() >> 32);
}
|