Advertisement
ulfben

constexpr rng

Jan 22nd, 2024
743
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.93 KB | None | 0 0
  1. //constexpr variant of the PCG (Permuted Congruential Generator) algorithm
  2. //See: https://www.pcg-random.org/download.html#minimal-c-implementation
  3. constexpr auto seed() noexcept{
  4.     std::uint64_t shifted = 0;      
  5.     const char* datetime = __DATE__ " " __TIME__;
  6.     for (const auto c : datetime) {
  7.         shifted <<= 8;
  8.         shifted |= c;
  9.     }
  10. #ifdef __COUNTER__
  11.     shifted ^= __COUNTER__;
  12. #endif
  13.     return shifted;
  14. }
  15. //ldexp(pcg32_random_r(&myrng), -32);
  16. struct PCG{
  17.     struct pcg32_random_t {
  18.         std::uint64_t state = 0;  
  19.         std::uint64_t inc=seed();
  20.     };
  21.     pcg32_random_t rng;
  22.     using result_type = double;
  23.  
  24.     constexpr result_type operator()() noexcept{    
  25.         return std::ldexp(pcg32_random_r(), -32); //https://mumble.net/~campbell/tmp/random_real.c
  26.         //return pcg32_random_r() * (1.0 / std::numeric_limits<std::uint32_t>::max());
  27.     }
  28.     constexpr std::uint32_t operator()(std::uint32_t bound) noexcept{    
  29.         return pcg32_boundedrand_r(bound);
  30.     }
  31.     static result_type constexpr min() noexcept {
  32.         return std::numeric_limits<result_type>::min();
  33.     }
  34.     static result_type constexpr max() noexcept {
  35.         return std::numeric_limits<result_type>::max();
  36.     }
  37.     private:
  38.     constexpr std::uint32_t pcg32_random_r() noexcept {
  39.         const std::uint64_t oldstate = rng.state;        
  40.         rng.state = oldstate * 6364136223846793005ULL + (rng.inc|1);        
  41.         const auto xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
  42.         const auto rot = oldstate >> 59u;    
  43.         return static_cast<std::uint32_t>((xorshifted >> rot) | (xorshifted << ((-rot) & 31)));
  44.     }
  45.    
  46.     constexper std::uint32_t pcg32_boundedrand_r(std::uint32_t bound) noexcept{
  47.         if (bound == 1) return 0;
  48.         std::uint32_t threshold = -bound % bound;    
  49.         for (;;) {
  50.             std::uint32_t r = pcg32_random_r();
  51.             if (r >= threshold){
  52.                 return r % bound;
  53.             }
  54.         }
  55.     }
  56. };
  57.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement