Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //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<std::uint32_t>::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<result_type>::min();
- }
- static result_type constexpr max() noexcept {
- return std::numeric_limits<result_type>::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<std::uint32_t>((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;
- }
- }
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement