diff --git a/research/try.cpp b/research/try.cpp index 8f8108be1..a52a2ea15 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -40,13 +40,13 @@ // 04/18 - investigate construction of static template members // 08/18 - Segfault when compiling some regular expressions for EventLog search // 10/18 - investigate insidious reinterpret cast +// 12/18 - investigate the trinomial random number algorithm from the C standard lib /** @file try.cpp - * Document an insidious wild cast, caused by the syntax `Type(arg)`. - * I was under the wrong assumption this would be handled equivalent to a constructor invocation. - * Seemingly it is rather handled as a C-style cast, i.e. equivalent to `(Type)arg`. - * @see [Question on Stackoverflow](https://stackoverflow.com/q/52782967/444796) + * Investigate the trinomial random number algorithm from the C standard library (actually GLibc 2.28). + * Actually this is work for the yoshimi project; we try there to build an in-tree version of the PRNG, + * in order to reduce dependencies to external libraries, which might change the sound of existing synth patches. */ typedef unsigned int uint; @@ -56,9 +56,10 @@ typedef unsigned int uint; #include "lib/util.hpp" #include +#include using std::string; -using util::isSameObject; +using boost::lexical_cast; @@ -67,35 +68,151 @@ using util::isSameObject; #define SHOW_EXPR(_XX_) \ cout << "Probe " << STRINGIFY(_XX_) << " ? = " << _XX_ <= 0) + prngval(); + return true; + } + uint32_t prngval() + { + uint32_t val = *fptr += uint32_t(*rptr); + uint32_t result = val >> 1; // Chucking least random bit. + // Rationale: it has a less-then optimal repetition cycle. + int32_t *end = &state[62]; + ++fptr; + if (fptr >= end) + { + fptr = state; + ++rptr; + } + else + { + ++rptr; + if (rptr >= end) + rptr = state; + } + // random_result holds number 0...INT_MAX + return result; + } + float numRandom() + { + return prngval() / float(INT32_MAX); + } + // random number in the range 0...INT_MAX + uint32_t randomINT() + { + return prngval(); + } +}; + +} int main (int, char**) { - Wau wau; - using ID = Miau &; - ID wuff = ID(wau); + StdlibPRNG oldGen; + TrinomialPRNG newGen; + + for (uint64_t seed=0; seed <= UINT32_MAX; ++seed) + { + oldGen.init(seed); + newGen.init(seed); + + for (uint i=0; i < 5*48000; ++i) + { + uint32_t oval = oldGen.prngval(); + uint32_t nval = newGen.prngval(); + if (oval != nval) + cout << "seed="<