constexpr_test_cpp_int_7.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. ///////////////////////////////////////////////////////////////
  2. // Copyright 2018 John Maddock. Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
  5. #include <boost/multiprecision/cpp_int.hpp>
  6. #include <iostream>
  7. struct kiss_rand
  8. {
  9. typedef std::uint64_t result_type;
  10. constexpr kiss_rand() : x(0x8207ebe160468b32uLL), y(0x2871283e01d45bbduLL), z(0x9c80bfd5db9680c9uLL), c(0x2e2683c2abb878b8uLL) {}
  11. constexpr kiss_rand(std::uint64_t seed) : x(seed), y(0x2871283e01d45bbduLL), z(0x9c80bfd5db9680c9uLL), c(0x2e2683c2abb878b8uLL) {}
  12. constexpr kiss_rand(std::uint64_t seed_x, std::uint64_t seed_y) : x(seed_x), y(seed_y), z(0x9c80bfd5db9680c9uLL), c(0x2e2683c2abb878b8uLL) {}
  13. constexpr kiss_rand(std::uint64_t seed_x, std::uint64_t seed_y, std::uint64_t seed_z) : x(seed_x), y(seed_y), z(seed_z), c(0x2e2683c2abb878b8uLL) {}
  14. constexpr std::uint64_t operator()()
  15. {
  16. return MWC() + XSH() + CNG();
  17. }
  18. private:
  19. constexpr std::uint64_t MWC()
  20. {
  21. std::uint64_t t = (x << 58) + c;
  22. c = (x >> 6);
  23. x += t;
  24. c += (x < t);
  25. return x;
  26. }
  27. constexpr std::uint64_t XSH()
  28. {
  29. y ^= (y << 13);
  30. y ^= (y >> 17);
  31. return y ^= (y << 43);
  32. }
  33. constexpr std::uint64_t CNG()
  34. {
  35. return z = 6906969069LL * z + 1234567;
  36. }
  37. std::uint64_t x, y, z, c;
  38. };
  39. inline constexpr void hash_combine(std::uint64_t& h, std::uint64_t k)
  40. {
  41. constexpr const std::uint64_t m = 0xc6a4a7935bd1e995uLL;
  42. constexpr const int r = 47;
  43. k *= m;
  44. k ^= k >> r;
  45. k *= m;
  46. h ^= k;
  47. h *= m;
  48. // Completely arbitrary number, to prevent 0's
  49. // from hashing to 0.
  50. h += 0xe6546b64;
  51. }
  52. template <std::size_t N>
  53. inline constexpr std::uint64_t string_to_hash(const char (&s)[N])
  54. {
  55. std::uint64_t hash(0);
  56. for (unsigned i = 0; i < N; ++i)
  57. hash_combine(hash, s[i]);
  58. return hash;
  59. }
  60. template <class UnsignedInteger>
  61. struct multiprecision_generator
  62. {
  63. typedef UnsignedInteger result_type;
  64. constexpr multiprecision_generator(std::uint64_t seed1) : m_gen64(seed1) {}
  65. constexpr multiprecision_generator(std::uint64_t seed1, std::uint64_t seed2) : m_gen64(seed1, seed2) {}
  66. constexpr multiprecision_generator(std::uint64_t seed1, std::uint64_t seed2, std::uint64_t seed3) : m_gen64(seed1, seed2, seed3) {}
  67. static constexpr result_type (min)()
  68. {
  69. return 0u;
  70. }
  71. static constexpr result_type (max)()
  72. {
  73. return ~result_type(0u);
  74. }
  75. constexpr result_type operator()()
  76. {
  77. result_type result(m_gen64());
  78. unsigned digits = 64;
  79. while (digits < std::numeric_limits<result_type>::digits)
  80. {
  81. result <<= 64;
  82. result |= m_gen64();
  83. digits += 64;
  84. }
  85. return result;
  86. }
  87. private:
  88. kiss_rand m_gen64;
  89. };
  90. template <class UnsignedInteger>
  91. constexpr UnsignedInteger nth_random_value(unsigned count = 0)
  92. {
  93. std::uint64_t date_hash = string_to_hash(__DATE__);
  94. std::uint64_t time_hash = string_to_hash(__TIME__);
  95. multiprecision_generator<UnsignedInteger> big_gen(date_hash, time_hash);
  96. for (unsigned i = 0; i < count; ++i)
  97. big_gen();
  98. return big_gen();
  99. }
  100. int main()
  101. {
  102. using namespace boost::multiprecision;
  103. constexpr uint1024_t rand = nth_random_value<uint1024_t>(1000);
  104. std::cout << std::hex << rand << std::endl;
  105. return 0;
  106. }