ZeroErr
Loading...
Searching...
No Matches
rng.h
Go to the documentation of this file.
1#pragma once
2
4
5#include <cstdint>
6#include <cstring>
7#include <vector>
8
10
11namespace zeroerr {
12
30class Rng final {
31public:
35 using result_type = uint64_t;
36
37 static uint64_t min();
38 static uint64_t max();
39
46 Rng(Rng const&) = delete;
47
52 Rng& operator=(Rng const&) = delete;
53
54 // moving is ok
55 Rng(Rng&&) noexcept = default;
56 Rng& operator=(Rng&&) noexcept = default;
57 ~Rng() noexcept = default;
58
67 Rng();
68
81 explicit Rng(uint64_t seed) noexcept;
82 Rng(uint64_t x, uint64_t y) noexcept;
83 Rng(std::vector<uint64_t> const& data);
84
89 Rng copy() const noexcept;
90
99 inline uint64_t operator()() noexcept {
100 auto x = mX;
101
102 mX = UINT64_C(15241094284759029579) * mY;
103 mY = rotl(mY - x, 27);
104
105 return x;
106 }
107
108 // This is slightly biased. See
109
126 inline uint32_t bounded(uint32_t range) noexcept {
127 uint64_t r32 = static_cast<uint32_t>(operator()());
128 auto multiresult = r32 * range;
129 return static_cast<uint32_t>(multiresult >> 32U);
130 }
131
132 // random double in range [0, 1]
133 // see http://prng.di.unimi.it/
134
142 inline double uniform01() noexcept {
143 auto i = (UINT64_C(0x3ff) << 52U) | (operator()() >> 12U);
144 // can't use union in c++ here for type puning, it's undefined behavior.
145 // std::memcpy is optimized anyways.
146 double d;
147 std::memcpy(&d, &i, sizeof(double));
148 return d - 1.0;
149 }
150
159 template <typename Container>
160 void shuffle(Container& container) noexcept {
161 auto size = static_cast<uint32_t>(container.size());
162 for (auto i = size; i > 1U; --i) {
163 using std::swap;
164 auto p = bounded(i); // number in [0, i)
165 swap(container[i - 1], container[p]);
166 }
167 }
168
176 std::vector<uint64_t> state() const;
177
178private:
179 static uint64_t rotl(uint64_t x, unsigned k) noexcept;
180
181 uint64_t mX;
182 uint64_t mY;
183};
184
185} // namespace zeroerr
186
Definition rng.h:30
Rng(Rng const &)=delete
Rng(Rng &&) noexcept=default
static uint64_t min()
Definition rng.cpp:54
uint32_t bounded(uint32_t range) noexcept
Definition rng.h:126
std::vector< uint64_t > state() const
Definition rng.cpp:46
uint64_t result_type
This RNG provides 64bit randomness.
Definition rng.h:35
double uniform01() noexcept
Definition rng.h:142
void shuffle(Container &container) noexcept
Definition rng.h:160
Rng copy() const noexcept
Definition rng.cpp:35
static uint64_t max()
Definition rng.cpp:56
Rng & operator=(Rng const &)=delete
uint64_t operator()() noexcept
Produces a 64bit random value. This should be very fast, thus it is marked as inline....
Definition rng.h:99
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_POP
Definition config.h:265
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH
Definition config.h:218
STL namespace.
Definition benchmark.cpp:17