//constexpr variant of the PCG (Permuted Congruential Generator) algorithm //See: https://www.pcg-random.org/download.html#minimal-c-implementation constexpr auto seed() noexcept{ std::uint64_t shifted = 0; const char* datetime = __DATE__ " " __TIME__; for (const auto c : datetime) { shifted <<= 8; shifted |= c; } #ifdef __COUNTER__ shifted ^= __COUNTER__; #endif return shifted; } //ldexp(pcg32_random_r(&myrng), -32); struct PCG{ struct pcg32_random_t { std::uint64_t state = 0; std::uint64_t inc=seed(); }; pcg32_random_t rng; using result_type = double; constexpr result_type operator()() noexcept{ return std::ldexp(pcg32_random_r(), -32); //https://mumble.net/~campbell/tmp/random_real.c //return pcg32_random_r() * (1.0 / std::numeric_limits::max()); } constexpr std::uint32_t operator()(std::uint32_t bound) noexcept{ return pcg32_boundedrand_r(bound); } static result_type constexpr min() noexcept { return std::numeric_limits::min(); } static result_type constexpr max() noexcept { return std::numeric_limits::max(); } private: constexpr std::uint32_t pcg32_random_r() noexcept { const std::uint64_t oldstate = rng.state; rng.state = oldstate * 6364136223846793005ULL + (rng.inc|1); const auto xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; const auto rot = oldstate >> 59u; return static_cast((xorshifted >> rot) | (xorshifted << ((-rot) & 31))); } constexper std::uint32_t pcg32_boundedrand_r(std::uint32_t bound) noexcept{ if (bound == 1) return 0; std::uint32_t threshold = -bound % bound; for (;;) { std::uint32_t r = pcg32_random_r(); if (r >= threshold){ return r % bound; } } } };