28 #ifndef OPENRAND_SQUARES_H_
29 #define OPENRAND_SQUARES_H_
31 #include <openrand/base_state.h>
36 #define K 0xc58efd154ce32f6d
51 OPENRAND_DEVICE
unsigned int get_digit(uint64_t i,
char *mask) {
54 while (mask[j] == 0) j++;
61 OPENRAND_DEVICE uint64_t hash_seed(uint32_t seed) {
62 constexpr uint64_t factorials[16] = {
65 40320, 362880, 3628800, 39916800,
66 479001600, 6227020800, 87178291200, 1307674368000};
67 uint64_t base = (1ULL << 60);
68 uint64_t i =
static_cast<uint64_t
>(seed);
74 char mask[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
79 uint64_t v = factorials[n];
80 unsigned int d = get_digit(i / v, mask);
91 unsigned int d = get_digit(0, mask);
112 OPENRAND_DEVICE
Squares(uint32_t seed, uint32_t ctr,
113 uint32_t global_seed = openrand::DEFAULT_GLOBAL_SEED)
114 : seed(hash_seed(seed) ^ global_seed), counter(ctr) {
117 template <
typename T = u
int32_t>
118 OPENRAND_DEVICE T draw() {
119 auto round = [](uint64_t x, uint64_t w) {
121 return (x >> 32) | (x << 32);
124 uint64_t ctr = (
static_cast<uint64_t
>(counter) << 32) | _ctr;
125 uint64_t x = ctr * seed;
127 uint64_t z = y + seed;
129 if constexpr (std::is_same_v<T, uint32_t>) {
133 return static_cast<uint32_t
>((x * x + z) >> 32);
139 return x ^ ((x * x + y) >> 32);
145 const uint32_t counter = 0;
Base class for random number generators.
Definition: base_state.h:50
OPENRAND_DEVICE Squares(uint32_t seed, uint32_t ctr, uint32_t global_seed=openrand::DEFAULT_GLOBAL_SEED)
Construct a new Squares generator.
Definition: squares.h:112