Back to blog
Field notes · random

Math.random() is a PRNG. Your d100 Has Measurable Bias.

ECMA-262 §21.1.2.13 explicitly does not require Math.random to be a CSPRNG, and 2^32 mod 100 = 96, so Math.floor(Math.random() * 100) + 1 is biased toward faces 1-96 by 96 / 2^32 per roll. This roller uses crypto.getRandomValues + Lemire 2019 rejection sampling, and a live Pearson χ² histogram lets you flip the toggle off and watch the p-value collapse.

6 min readVectobox Team