36 進数と文字の偏り2007年08月22日 03時15分

36 進数表記に変換することによるランダムな文字列生成は偏りが大きいよという話。なるほど。というわけで JavaScript の場合を調べてみた。といっても統計学的な検証とかよくわからないのでざっと見た感じで。

Math.random().toString(36)
整数部は当然 0 のはずなので小数部だけ。Firefox は最後の桁に偏りが見られる。IE はすべての桁がそれなりにばらけている。逆に言えば最後の桁が 0 ということも。Safari は後半部分の偏りが大きい。最後の桁は 9 の倍数に大きく偏っている。
Math.floor(Number.MAX_VALUE * Math.random()).toString(36)
Firefox は前後 2 桁に偏りが見られる。最後の桁は 4 の倍数しか表れない。Opera、Safari も均等にばらけてくるのは 3 桁目から。中盤移行は 4 の倍数しか表れない。

Firefox での偏りが相対的に小さいのは、SpiderMonkey では Bigint という独自の構造体を用いて n 進数表記に変換してるからみたいだ。一方 JavaScriptCore では double 型と fmod を用いて変換を行っている

その違いがどうしてこのような結果をもたらすかについては教えてエロい人だが、とりあえず一様性を求めるなら Math.random().toString(36).substring(2, 10) などとしたほうがいいようだ。