For enjoyers of French-Canadian random number generation papers/books, there's also this excellent book on non-uniform random variate generation by Luc Devroye: http://luc.devroye.org/rnbookindex.html
I like how the earliest and easiest PRNGs are making a comeback:
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.
I wouldn't recemmend that without a 128 bit variables. The truncation is required to make the generator non predictable, otherwise you leak to much state.
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).
You also have to love that the middle square method is by von Neumann[0], infinitely quotable about random numbers ("Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin"), way back in 1949. As a small child he saw his mother daydreaming, and asked her what she was computing...
The article references the SSJ Java package which is developed by the author and his colleagues. This provides implementations for many RNGs -- and some nice tools for simulations:
https://github.com/umontreal-simul/ssj