ulfben icon

constexpr rng

ulfben | PRO | 01/22/24 03:48:35 PM UTC | 0 ⭐ | 11977 👁️ | Never ⏰ | []
C++ |

1.93 KB

|

None

|

0 👍

/

0 👎

//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;
            }
        }
    }
};
 

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎