History of Uniform Random Number Generation (2017) [pdf]
informs-sim.org
informs-sim.org
First middle square method, just add a weyl sequence to it, and all statistical tests stop failing [0]
uint64_t x, weyl;
uint32_t msws(void) {
x = x * x + (weyl += 0xB5AD4ECEDA1CE2A9);
return x = (x >> 32) | (x << 32);
}
And now Collatz, just add a weyl sequence to it, and all statistical tests stop failing [1] __uint128_t x;
uint64_t a, weyl;
__uint128_t CWG128_64(void) {
x = (x | 1) * ((a += x) >> 1) ^ (weyl += 0xB5AD4ECEDA1CE2A9);
return a >> 48 ^ x;
}
The fun part is that the constant used in the weyl sequence is pretty much arbitrary, it just needs to be odd and not too regular.The more state of the art xoshiro, pcg, Romu, sfc64, tylo64, ... are still faster and probably safer tp use, but I like how especially the middle square weyl sequence PRNG can be very easily memorized: Square + weyl sequence, swap upper and lower bits, and return the truncated result. The weyl sequemce constant can be created with a rule of thumb: try choosing mostly destinct hex digits and make it odd.
uint64_t x = 0, w = 1;
uint64_t msws64(void) {
x = x * x + (w *= 0xe9acc0f334e93bd5ULL);
return (x = (x >> 32) | (x << 32)) ^ w;
}Alternatively, you can just call the 32 bit one twice and build a 64 bit value from the results.
Edit: I didn't see that you changed the algorithm more than removing the truncation. It is honestly suprizingly good for exposing that much state, but it fails PractRand after 16 GB.
It is honestly suprizingly good and hasn't failed PractRand yet (I'm at >64 GB).
RAND used to cut copies of the punch card deck for anyone who asked, but I'm sadly unable to find anyone who's still got a copy.
Way too slow on Alphas at the time for primary use but OK for seed at the time.
I still remember SGI publishing LavaRand, using lava lamps and cc'd cameras as an entropy source around the same time.