X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Frand%2FGaloisLFSR.hpp;h=2ee476b6e321cc5d0298993b75e134b0727aeaad;hb=33b37e7242e4cbfa76e4a0d6e5bb54223b541162;hp=88a1d37e899f1b26e369a727a804d7755ba7d33e;hpb=b7d09e1e35ef90282c97509e0020b20db3c7ea9f;p=blank.git diff --git a/src/rand/GaloisLFSR.hpp b/src/rand/GaloisLFSR.hpp index 88a1d37..2ee476b 100644 --- a/src/rand/GaloisLFSR.hpp +++ b/src/rand/GaloisLFSR.hpp @@ -11,10 +11,25 @@ class GaloisLFSR { public: // seed should be non-zero - explicit GaloisLFSR(std::uint64_t seed) noexcept; + explicit GaloisLFSR(std::uint64_t seed) noexcept + : state(seed) { + if (state == 0) { + state = 1; + } + } // get the next bit - bool operator ()() noexcept; + bool operator ()() noexcept { + bool result = state & 1; + state >>= 1; + if (result) { + state |= 0x8000000000000000; + state ^= mask; + } else { + state &= 0x7FFFFFFFFFFFFFFF; + } + return result; + } template T operator ()(T &out) noexcept { @@ -27,12 +42,28 @@ public: return out = static_cast(state); } + template + T Next() noexcept { + T next; + return (*this)(next); + } + + template + typename Container::reference From(Container &c) { + return c[Next() % c.size()]; + } + template + typename Container::const_reference From(const Container &c) { + return c[Next() % c.size()]; + } + private: std::uint64_t state; // bits 64, 63, 61, and 60 set to 1 (counting from 1 lo to hi) static constexpr std::uint64_t mask = 0xD800000000000000; }; + } #endif