18
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

参照透過なランダム関数を探してたら、謎の数字と出会う

Posted at

###9301 49297 233280
この数字に見覚えのある奇特な方はいますか?
まさかいないですよね・・・

##Math.random()は毎回違う結果が出る( != 参照透過)
最初に確認しておきたいのは、参照透過とはざっくり言うと「同じ環境では毎回同じ結果になる」ということです。

しかしMath.random()はたしか時間をもとにしてるので同じ環境でも時間が違うから同じ結果にならないということですね。(同じ時空に戻れば同じ結果になると思いますがw)

関数型言語が特にQiitaで盛り上がっていますよね。
そこにちょっと気になった文章がありました。

Math.randomは呼び出すごとに異なる値を返す可能性があるので参照透明ではありません。

from 関数型言語のウソとホント

たしかに・・・

そうきたら・・・

( ´_ゝ`) < JSでも参照透過な乱数を見てみたい...

##探してみた

いや、もしかしたらあるの?ちょっと探してみた。

現に他言語、最近だとC++とかにはあったのを見た気がします。
シード(ソルト)が同じであれば、常に同じ結果を返すランダム関数が欲しくなりました。

##そもそもMath.random()のソースは?
「現在時刻のミリ秒」をシードとしているそうです。
しかもオーバーロードできないとか問題もあり、シード値を変えることはできないんだとか。
詳しくは、
[JavaScript]そこそこ精度の高い乱数を手に入れる
http://outofmem.tumblr.com/post/75785092410/javascript

##なんか変なコードがあった
なんかわけのわからないコードがありまして、実際CodeRunnerとChromeで実行したら同じ結果にもなりました。(当たり前ですが)


// the initial seed
Math.seed = 6;
 
// in order to work 'Math.seed' must NOT be undefined,
// so in any case, you HAVE to provide a Math.seed
Math.seededRandom = function(max, min) {
    max = max || 1;
    min = min || 0;
 
    Math.seed = (Math.seed * 9301 + 49297) % 233280;
    var rnd = Math.seed / 233280;
 
    return min + rnd * (max - min);
}

console.log(Math.seededRandom(4));//1.8021776406035666

Generate Repeatable Random Numbers (in JS)
http://indiegamr.com/generate-repeatable-random-numbers-in-js/

そこにこんなことが書いてあるんですね

You may ask: Why ‘(seed * 9301 + 49297) % 233280‘ ?!
The answer is both simple&complicated: The combination of 9301, 49297 and 233280 provide a very even distributed set of “random” numbers. Please don’t ask WHY – that’s the complicated part, some very smart people figured out those numbers quite some time ago, and I also cannot tell you how they did it. But as allways: Google is your friend ;-)

要約すると・・・
「答えは単純だし複雑なんだ。だからなぜかと問わないで黙って使え」
なんかこわい・・・

最後に「Googleは君の友達だよ」と書いてあったのでググってみました。
そしたらこんな文言がありました。

A quick search of Google Books shows these numbers (9301, 49297, 233280) have been used in a number of references
...中略...
The oldest is 1977's Computer methods for mathematical computations by George Elmer Forsythe, Michael A. Malcolm, Cleve B. Moler (Prentice-Hall), although Google doesn't show where the text was used in the book so it cannot be verified.

Original source of (seed * 9301 + 49297) % 233280 random algorithm?
http://programmers.stackexchange.com/questions/260969/original-source-of-seed-9301-49297-233280-random-algorithm

要約すると
「Googleブックス検索で本文検索をしてもその数字は出てくるから安心しろ」

古くからあるアルゴリズムっぽいですね。

・・・

使おうとは思いませんが ←

18
17
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?