-
Notifications
You must be signed in to change notification settings - Fork 0
/
rjd_rng.h
54 lines (42 loc) · 1.05 KB
/
rjd_rng.h
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
#pragma once
#define RJD_RNG_H 1
struct rjd_rng
{
uint64_t seed;
uint64_t state;
};
struct rjd_rng rjd_rng_init(uint64_t seed);
uint64_t rjd_rng_next(struct rjd_rng* rng);
double rjd_rng_float(struct rjd_rng* rng);
int32_t rjd_rng_range32(struct rjd_rng* rng, int32_t min_inclusive, int32_t max_exclusive);
#if RJD_IMPL
struct rjd_rng rjd_rng_init(uint64_t seed)
{
struct rjd_rng rng = { seed, seed };
return rng;
}
uint64_t rjd_rng_next(struct rjd_rng* rng)
{
rng->state ^= rng->state << 15;
rng->state ^= rng->state >> 3;
rng->state ^= rng->state << 52;
return rng->state;
}
double rjd_rng_float(struct rjd_rng* rng)
{
uint64_t next = rjd_rng_next(rng) % 1000001ull;
return (double)next / 1000000.0;
}
int32_t rjd_rng_range32(struct rjd_rng* rng, int32_t min_inclusive, int32_t max_exclusive)
{
if (max_exclusive < min_inclusive) {
return max_exclusive;
}
int32_t range = max_exclusive - min_inclusive;
if (range == 0) {
return min_inclusive;
}
uint64_t next = rjd_rng_next(rng);
return min_inclusive + (next % range);
}
#endif // RJD_IMPL