-
Notifications
You must be signed in to change notification settings - Fork 0
/
xorshift.hpp
67 lines (55 loc) · 1.9 KB
/
xorshift.hpp
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
62
63
64
65
66
67
#ifndef XORSHIFT_HPP
#define XORSHIFT_HPP
/* Xorshift random number generator.
* This class is a direct implementation of the version with period 2**128-1
* found it the paper http://www.jstatsoft.org/v08/i14/paper.
*
* The values a, b and c should be chosen in a special way;
* the paper suggest the triples [5, 14, 1], [15, 4, 21], [23, 24, 3], [5, 12, 29].
*
* For convenience, a typedef to xorshift using the second triple is given.
*/
#include <cstdint>
#include <chrono>
template < std::uint32_t a, std::uint32_t b, std::uint32_t c >
struct xorshift_t {
// State bytes
std::uint32_t x, y, z, w;
/* Default constructor.
* Initialize every state bytes based on the current time.
*/
xorshift_t();
/* Constructor that allows the initial seed specification.
*/
xorshift_t( std::uint32_t x, std::uint32_t y,
std::uint32_t z, std::uint32_t w )
:
x(x), y(y), z(z), w(w)
{}
/* Uninteresting constructor that just copies the same input to the state bytes.
* This constructor exists mainly to make it closer to C++'s random engines.
*/
xorshift_t( std::uint32_t seed ):
x(seed), y(seed), z(seed), w(seed)
{}
/* Generates a new random number
* and advances the generator's internal state.
*/
std::uint32_t operator()();
};
// Convenience typedef
using xorshift = xorshift_t<15, 4, 21>;
template < std::uint32_t a, std::uint32_t b, std::uint32_t c >
xorshift_t< a, b, c >::xorshift_t() {
// seed is a 64-bit number.
auto seed = std::chrono::system_clock::now().time_since_epoch().count();
x = z = seed & ((1llu << 32) - 1);
y = w = seed >> 32;
}
template < std::uint32_t a, std::uint32_t b, std::uint32_t c >
std::uint32_t xorshift_t< a, b, c >::operator()() {
std::uint32_t t = x ^ (x << a);
x = y; y = z; z = w;
return w = (w ^ (w >> c)) ^ (t ^ (t >> b));
}
#endif // XORSHIFT_HPP