openMSX
random.hh
Go to the documentation of this file.
1#ifndef RANDOM_HH
2#define RANDOM_HH
3
4#include <random>
5
8[[nodiscard]] inline auto& global_urng()
9{
10 static std::minstd_rand0 u;
11 return u;
12}
13
16inline void randomize()
17{
18 static std::random_device rd;
19 global_urng().seed(rd());
20}
21
24[[nodiscard]] inline bool random_bool()
25{
26 // Note: this is only 100% uniform if 'generator.max() -
27 // generator().min() + 1' is even. This is the case for
28 // std::minstd_rand0.
29 auto& generator = global_urng();
30 return generator() & 1;
31}
32
38[[nodiscard]] inline int random_int(int from, int thru)
39{
40 static std::uniform_int_distribution<int> d;
41 using parm_t = decltype(d)::param_type;
42 return d(global_urng(), parm_t{from, thru});
43}
44
50[[nodiscard]] inline float random_float(float from, float upto)
51{
52 static std::uniform_real_distribution<float> d;
53 using parm_t = decltype(d)::param_type;
54 return d(global_urng(), parm_t{from, upto});
55}
56
67[[nodiscard]] inline uint32_t random_32bit()
68{
69 static std::uniform_int_distribution<uint32_t> d;
70 using parm_t = decltype(d)::param_type;
71 return d(global_urng(), parm_t{0, 0xffffffff});
72}
73
74
75// Compile-time random numbers
76
77// Constexpr "Permuted Congruential Generator" (PCG)
78// generated random numbers at compile-time
79// (or it shifts the problem to obtaining a random seed at compile time)
80// Based upon:
81// C++ Weekly - Ep 44 - constexpr Compile Time Random
82// https://www.youtube.com/watch?v=rpn_5Mrrxf8
83template<uint64_t SEED>
84struct PCG
85{
86 constexpr uint32_t operator()()
87 {
88 // Advance internal state
89 auto oldState = state;
90 state = oldState * 6364136223846793005ULL + (SEED | 1);
91
92 // Calculate output function (XSH RR), uses old state for max
93 // ILP
94 auto xorShifted = uint32_t(((oldState >> 18) ^ oldState) >> 27);
95 auto rot = int(oldState >> 59);
96 return (xorShifted >> rot) | (xorShifted << ((-rot) & 31));
97 }
98
99private:
100 uint64_t state = SEED;
101};
102
103// Turns a random 32-bit integer into a random float in the range [0, 1).
104[[nodiscard]] constexpr float getCanonicalFloat(uint32_t u)
105{
106 uint32_t b = 1 << 23;
107 uint32_t m = b - 1;
108 return float(u & m) / float(b);
109}
110
111#endif
auto & global_urng()
Return reference to a (shared) global random number generator.
Definition random.hh:8
void randomize()
Seed the (shared) random number generator.
Definition random.hh:16
int random_int(int from, int thru)
Return a random integer in the range [from, thru] (note: closed interval).
Definition random.hh:38
uint32_t random_32bit()
Return a random 32-bit value.
Definition random.hh:67
constexpr float getCanonicalFloat(uint32_t u)
Definition random.hh:104
bool random_bool()
Return a random boolean value.
Definition random.hh:24
float random_float(float from, float upto)
Return a random float in the range [from, upto) (note: half-open interval).
Definition random.hh:50
Definition random.hh:85
constexpr uint32_t operator()()
Definition random.hh:86