mersenne64.h 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. #pragma once
  2. #include <util/system/defaults.h>
  3. class IInputStream;
  4. namespace NPrivate {
  5. class TMersenne64 {
  6. static constexpr int NN = 312;
  7. public:
  8. inline TMersenne64(ui64 s = ULL(19650218))
  9. : mti(NN + 1)
  10. {
  11. InitGenRand(s);
  12. }
  13. inline TMersenne64(const ui64* keys, size_t len) noexcept
  14. : mti(NN + 1)
  15. {
  16. InitByArray(keys, len);
  17. }
  18. TMersenne64(IInputStream& input);
  19. inline ui64 GenRand() noexcept {
  20. if (mti >= NN) {
  21. InitNext();
  22. }
  23. ui64 x = mt[mti++];
  24. x ^= (x >> 29) & ULL(0x5555555555555555);
  25. x ^= (x << 17) & ULL(0x71D67FFFEDA60000);
  26. x ^= (x << 37) & ULL(0xFFF7EEE000000000);
  27. x ^= (x >> 43);
  28. return x;
  29. }
  30. private:
  31. void InitNext() noexcept;
  32. void InitGenRand(ui64 seed) noexcept;
  33. void InitByArray(const ui64* init_key, size_t key_length) noexcept;
  34. private:
  35. ui64 mt[NN];
  36. int mti;
  37. };
  38. } // namespace NPrivate