123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- ///////////////////////////////////////////////////////////////
- // Copyright 2018 John Maddock. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
- #include <boost/multiprecision/cpp_int.hpp>
- #include <iostream>
- struct kiss_rand
- {
- typedef std::uint64_t result_type;
- constexpr kiss_rand() : x(0x8207ebe160468b32uLL), y(0x2871283e01d45bbduLL), z(0x9c80bfd5db9680c9uLL), c(0x2e2683c2abb878b8uLL) {}
- constexpr kiss_rand(std::uint64_t seed) : x(seed), y(0x2871283e01d45bbduLL), z(0x9c80bfd5db9680c9uLL), c(0x2e2683c2abb878b8uLL) {}
- constexpr kiss_rand(std::uint64_t seed_x, std::uint64_t seed_y) : x(seed_x), y(seed_y), z(0x9c80bfd5db9680c9uLL), c(0x2e2683c2abb878b8uLL) {}
- 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) {}
- constexpr std::uint64_t operator()()
- {
- return MWC() + XSH() + CNG();
- }
- private:
- constexpr std::uint64_t MWC()
- {
- std::uint64_t t = (x << 58) + c;
- c = (x >> 6);
- x += t;
- c += (x < t);
- return x;
- }
- constexpr std::uint64_t XSH()
- {
- y ^= (y << 13);
- y ^= (y >> 17);
- return y ^= (y << 43);
- }
- constexpr std::uint64_t CNG()
- {
- return z = 6906969069LL * z + 1234567;
- }
- std::uint64_t x, y, z, c;
- };
- inline constexpr void hash_combine(std::uint64_t& h, std::uint64_t k)
- {
- constexpr const std::uint64_t m = 0xc6a4a7935bd1e995uLL;
- constexpr const int r = 47;
- k *= m;
- k ^= k >> r;
- k *= m;
- h ^= k;
- h *= m;
- // Completely arbitrary number, to prevent 0's
- // from hashing to 0.
- h += 0xe6546b64;
- }
- template <std::size_t N>
- inline constexpr std::uint64_t string_to_hash(const char (&s)[N])
- {
- std::uint64_t hash(0);
- for (unsigned i = 0; i < N; ++i)
- hash_combine(hash, s[i]);
- return hash;
- }
- template <class UnsignedInteger>
- struct multiprecision_generator
- {
- typedef UnsignedInteger result_type;
- constexpr multiprecision_generator(std::uint64_t seed1) : m_gen64(seed1) {}
- constexpr multiprecision_generator(std::uint64_t seed1, std::uint64_t seed2) : m_gen64(seed1, seed2) {}
- constexpr multiprecision_generator(std::uint64_t seed1, std::uint64_t seed2, std::uint64_t seed3) : m_gen64(seed1, seed2, seed3) {}
- static constexpr result_type (min)()
- {
- return 0u;
- }
- static constexpr result_type (max)()
- {
- return ~result_type(0u);
- }
- constexpr result_type operator()()
- {
- result_type result(m_gen64());
- unsigned digits = 64;
- while (digits < std::numeric_limits<result_type>::digits)
- {
- result <<= 64;
- result |= m_gen64();
- digits += 64;
- }
- return result;
- }
- private:
- kiss_rand m_gen64;
- };
- template <class UnsignedInteger>
- constexpr UnsignedInteger nth_random_value(unsigned count = 0)
- {
- std::uint64_t date_hash = string_to_hash(__DATE__);
- std::uint64_t time_hash = string_to_hash(__TIME__);
- multiprecision_generator<UnsignedInteger> big_gen(date_hash, time_hash);
- for (unsigned i = 0; i < count; ++i)
- big_gen();
- return big_gen();
- }
- int main()
- {
- using namespace boost::multiprecision;
- constexpr uint1024_t rand = nth_random_value<uint1024_t>(1000);
- std::cout << std::hex << rand << std::endl;
- return 0;
- }
|