X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Frand%2FGaloisLFSR.hpp;h=f8a61e23f3f7c721689d7e0ff4a2404aa671f412;hb=fab49d91255ef7d265817213c3da7e5f81df97a0;hp=395ff8f0546cc7b75cf111a4b996a7705052f29b;hpb=41652fb3d73f12e6ae4ce7380244a75a4f5c6797;p=blank.git diff --git a/src/rand/GaloisLFSR.hpp b/src/rand/GaloisLFSR.hpp index 395ff8f..f8a61e2 100644 --- a/src/rand/GaloisLFSR.hpp +++ b/src/rand/GaloisLFSR.hpp @@ -1,6 +1,7 @@ #ifndef BLANK_RAND_GALOISLFSR_HPP_ #define BLANK_RAND_GALOISLFSR_HPP_ +#include #include #include @@ -12,7 +13,11 @@ class GaloisLFSR { public: // seed should be non-zero explicit GaloisLFSR(std::uint64_t seed) noexcept - : state(seed) { } + : state(seed) { + if (state == 0) { + state = 1; + } + } // get the next bit bool operator ()() noexcept { @@ -38,12 +43,36 @@ public: return out = static_cast(state); } + /// special case for randrom(boolean), since static_cast(0b10) == true + bool operator ()(bool &out) noexcept { + return out = operator ()(); + } + template T Next() noexcept { T next; return (*this)(next); } + float SNorm() noexcept { + return float(Next()) * (1.0f / 2147483647.5f) - 1.0f; + } + + float UNorm() noexcept { + return float(Next()) * (1.0f / 4294967295.0f); + } + + template + typename Container::reference From(Container &c) { + assert(c.size() > 0); + return c[Next() % c.size()]; + } + template + typename Container::const_reference From(const Container &c) { + assert(c.size() > 0); + 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)