Fix uint32 multiplication in PCG next and peel functions - #28
Conversation
|
Update: here are the Dieharder results for the current (1.0.0) buggy version and for the proposed fix: pcgelmbuggy_c_result.txt Summary
So even taking these summary results blindly, it seems fixing A related question is, if this fix gets accepted in some form (changing the random numbers generated for a given seed), should |
|
Some more progress on this: I ran Dieharder with But then I ran the TestU01 BigCrush tests, and I wrote a blogpost about (among other things) this exploration: https://martin.janiczek.cz/2026/08/02/improving-elm-prng.html |
JavaScript multiplication loses precision on large numbers (when the result gets above
Number.MAX_SAFE_INTEGER = 2^53 - 1). Inelm/randomthis happens innextandpeel.The JavaScript solution is to use
Math.imul()(MDN), which in Elm we need to emulate by splitting the numbers in two 16bit halves and carefully manipulating them, unless a new stdlib primitive is added which callsMath.imul.The consequence for
elm/randomis that the numbers returned fromnextand the state advanced bypeelslowly diverges from the equivalent C implementation.For
initialSeed = 123456789->state = 1102901571,incr = 1013904223, we get:nextnextIt's unclear to me what the severity of this deviance from PCG is: we'd need to run Dieharder or some other randomness statistical test suite on the Elm numbers. I presume since precision is lost in the multiplication (the upper 11 bits or so), the mixing stops being as good over time and some statistical properties get lost, but I haven't run the tests (yet).
This PR makes Elm return the same number sequences as C would.