闇PHP勉強会でphpのランダマイズについて話してきたこと

導入

"配列のランダマイズ、出来ますか?" を読み、php の場合はどうなの? と思ったので、調べてみましたというお話。

結論としては、4.3.0 以降の php では等分散されます。

ただ、疑似乱数生成器が libc 依存なため OS によって異なる結果となるので、異なる環境での再現性が必要な場合は、mt_rand 使って再実装した方が良いんじゃないかなと。

mt_rand の精度について

メルセンヌツイスタの精度って32bit だけど、64bit 版の場合の mt_rand はどうなの? という質問を受けまして、
合成して 64bit 作ってると言ってしまいましたが、アレは大嘘でした。ごめんなさい。

32bit で生成した乱数を、long にキャストして返してますね。
それどころか、(php_rand の挙動に合わせる? ために)1bit 右シフトして 31bit にしています。

うむむ。。。

乱数の再現性について

ちとここについては。説明不足だったかな。
多くの疑似乱数生成器では、同じ seed を与えると、常に同じ順序で乱数が生成されます。

srand(1) した後に rand() を何度か呼んでみると分かりますが、順に同じ値が返ってくると思います。

ただ、スライドでも書いたとおり、rand は libc 依存なため、異なる環境だと、同じ seed でも異なる乱数が生成されてしまします。

これが mt_rand の場合は実装に依存した動きになるため、異なる環境でも seed が同じならば 、常に同じ順で乱数が生成されるというわけです。

mt_srand(1) をすれば、どの環境でも mt_rand() は順に同じ値(1244335972→15217923→1546885062)が返るということです。 (もちろん、php のバージョンによって実装が変化する可能性はありますが)

ま、これが必要となるケースの場合、 php を選択するなという話になると思いますけど。

多いですね