1 #ifndef BLOBS_MATH_GALOISLFSR_HPP_
2 #define BLOBS_MATH_GALOISLFSR_HPP_
15 // seed should be non-zero
16 explicit GaloisLFSR(std::uint64_t seed) noexcept
24 bool operator ()() noexcept {
25 bool result = state & 1;
28 state |= 0x8000000000000000;
31 state &= 0x7FFFFFFFFFFFFFFF;
37 T operator ()(T &out) noexcept {
38 constexpr int num_bits =
39 std::numeric_limits<T>::digits +
40 std::numeric_limits<T>::is_signed;
41 for (int i = 0; i < num_bits; ++i) {
44 return out = static_cast<T>(state);
47 /// special case for randrom(boolean), since static_cast<bool>(0b10) == true
48 bool operator ()(bool &out) noexcept {
49 return out = operator ()();
58 double SNorm() noexcept {
59 return (2.0 * UNorm()) - 1.0;
62 double UNorm() noexcept {
63 return double(Next<std::uint32_t>()) * (1.0 / double(std::numeric_limits<std::uint32_t>::max()));
66 unsigned int UInt(unsigned int below) noexcept {
67 return ((unsigned int)(UNorm() * double(below))) % below;
70 template<class Container>
71 typename Container::reference From(Container &c) {
73 return c[Next<typename Container::size_type>() % c.size()];
75 template<class Container>
76 typename Container::const_reference From(const Container &c) {
78 return c[Next<typename Container::size_type>() % c.size()];
83 // bits 64, 63, 61, and 60 set to 1 (counting from 1 lo to hi)
84 static constexpr std::uint64_t mask = 0xD800000000000000;