cperl
cperl copied to clipboard
Replace the extremely poor drand48 with a proper one
Note that the perl5 design choices for drand48() are extremely poor. (but not entirely unexpected from p5p).
1st: Taking the primitive freebsd rand48() they use ldexp(.., -48) to expand the 48 bits to a double, not the much faster bitmasking. ldexp uses 5 branches and 1-2 multiplications. This is ~2x slower than needed. The FreeBSD original is sane here, but even gsl is doing the same. Wonder who was first.
2nd: Masking to 48 bits not 53 makes creating uniform double values much harder. Normally you would create 64-bit numbers as with every other rng. Then you have proper int ranges as well as double.
Use a good one instead, which works on 32bit and 64bit systems, producing full range ints and doubles, and much faster. e.g wyrand. See https://rurban.github.io/dieharder/QUALITY.html (look for drand48 at the bottom).
And while we are here, seperate pp_rand into int and double methods. It makes not much sense to produce costly doubles, when only int values are requested.
Already filed at #10, then I thought PCG or xoroshiro128+ would be best (before actually testing them)