1
#pragma once
2
#include <math.h>
3
#include <stdint.h>
4

5
#ifdef _WIN32
6
#define inline __forceinline
7
#endif
8

9
#define RK_STATE_LEN 624
10

11
#define N 624
12
#define M 397
13
#define MATRIX_A 0x9908b0dfUL
14
#define UPPER_MASK 0x80000000UL
15
#define LOWER_MASK 0x7fffffffUL
16

17
typedef struct s_mt19937_state {
18
  uint32_t key[RK_STATE_LEN];
19
  int pos;
20
} mt19937_state;
21

22
extern void mt19937_seed(mt19937_state *state, uint32_t seed);
23

24
extern void mt19937_gen(mt19937_state *state);
25

26
/* Slightly optimized reference implementation of the Mersenne Twister */
27 1
static inline uint32_t mt19937_next(mt19937_state *state) {
28
  uint32_t y;
29

30 1
  if (state->pos == RK_STATE_LEN) {
31
    // Move to function to help inlining
32 1
    mt19937_gen(state);
33
  }
34 1
  y = state->key[state->pos++];
35

36
  /* Tempering */
37 1
  y ^= (y >> 11);
38 1
  y ^= (y << 7) & 0x9d2c5680UL;
39 1
  y ^= (y << 15) & 0xefc60000UL;
40 1
  y ^= (y >> 18);
41

42 1
  return y;
43
}
44

45
extern void mt19937_init_by_array(mt19937_state *state, uint32_t *init_key,
46
                                  int key_length);
47

48 1
static inline uint64_t mt19937_next64(mt19937_state *state) {
49 1
  return (uint64_t)mt19937_next(state) << 32 | mt19937_next(state);
50
}
51

52
static inline uint32_t mt19937_next32(mt19937_state *state) {
53 1
  return mt19937_next(state);
54
}
55

56 1
static inline double mt19937_next_double(mt19937_state *state) {
57 1
  int32_t a = mt19937_next(state) >> 5, b = mt19937_next(state) >> 6;
58 1
  return (a * 67108864.0 + b) / 9007199254740992.0;
59
}
60

61
void mt19937_jump(mt19937_state *state);

Read our documentation on viewing source code .

Loading