/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2015-2016 Danny Robson */ #include "xorshift.hpp" #include "../debug.hpp" #include using cruft::rand::xorshift; /////////////////////////////////////////////////////////////////////////////// template xorshift::xorshift (T seed): m_state (seed) { if (!m_state) throw std::invalid_argument ("xorshift seed must not be zero"); } /////////////////////////////////////////////////////////////////////////////// // setup the constants a, b, and c. we use the values from the example // generators provided in Marsaglia's paper. template struct constants; //----------------------------------------------------------------------------- template <> struct constants { static constexpr uint32_t a = 13u; static constexpr uint32_t b = 17u; static constexpr uint32_t c = 5u; }; //----------------------------------------------------------------------------- template <> struct constants { static constexpr uint64_t a = 13u; static constexpr uint64_t b = 7u; static constexpr uint64_t c = 17u; }; /////////////////////////////////////////////////////////////////////////////// template typename xorshift::result_type xorshift::operator() (void) { m_state ^= m_state >> constants::a; m_state ^= m_state << constants::b; m_state ^= m_state >> constants::c; CHECK_NEZ (m_state); return m_state; }; /////////////////////////////////////////////////////////////////////////////// template typename xorshift::result_type xorshift::min (void) { return 1u; } //----------------------------------------------------------------------------- template typename xorshift::result_type xorshift::max (void) { return std::numeric_limits::max (); } /////////////////////////////////////////////////////////////////////////////// template void xorshift::discard (unsigned count) { while (count--) (*this)(); } /////////////////////////////////////////////////////////////////////////////// template struct cruft::rand::xorshift; template struct cruft::rand::xorshift;