blob: 1b39e0b6434c3f292e58b4059d62afe33f352659 (
plain)
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
|
#pragma once
#include <math.h>
#include <stdint.h>
#ifdef _WIN32
#define inline __forceinline
#endif
#define RK_STATE_LEN 624
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL
#define UPPER_MASK 0x80000000UL
#define LOWER_MASK 0x7fffffffUL
typedef struct s_mt19937_state {
uint32_t key[RK_STATE_LEN];
int pos;
} mt19937_state;
extern void mt19937_seed(mt19937_state *state, uint32_t seed);
extern void mt19937_gen(mt19937_state *state);
/* Slightly optimized reference implementation of the Mersenne Twister */
static inline uint32_t mt19937_next(mt19937_state *state) {
uint32_t y;
if (state->pos == RK_STATE_LEN) {
// Move to function to help inlining
mt19937_gen(state);
}
y = state->key[state->pos++];
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return y;
}
extern void mt19937_init_by_array(mt19937_state *state, uint32_t *init_key,
int key_length);
static inline uint64_t mt19937_next64(mt19937_state *state) {
return (uint64_t)mt19937_next(state) << 32 | mt19937_next(state);
}
static inline uint32_t mt19937_next32(mt19937_state *state) {
return mt19937_next(state);
}
static inline double mt19937_next_double(mt19937_state *state) {
int32_t a = mt19937_next(state) >> 5, b = mt19937_next(state) >> 6;
return (a * 67108864.0 + b) / 9007199254740992.0;
}
void mt19937_jump(mt19937_state *state);
|