Rhinoのソースコードを調べて、それらが使用している疑似ランダム関数を見つけました。どうやらそれらはJava標準ライブラリで定義された関数にフォールバックします。Math.random
のドキュメントは次のようにMath.random
述べています。
0.0以上1.0未満の正の符号を持つdouble値を返します。戻り値は、その範囲から(ほぼ)均一に分布する疑似ランダムに選択されます。
このメソッドが最初に呼び出されると、式の場合とまったく同じように、単一の新しい疑似乱数ジェネレータが作成されます。
new java.util.Random
この新しい疑似乱数ジェネレータは、その後、このメソッドのすべての呼び出しに使用され、他の場所では使用されません。
このメソッドは適切に同期されているため、複数のスレッドで正しく使用できます。ただし、多くのスレッドが高速で疑似乱数を生成する必要がある場合は、各スレッドが独自の疑似乱数ジェネレーターを持つようにするための競合を減らすことができます。
だから私はドキュメントをチェックしてこれjava.util.Random
を見つけました(デフォルトのコンストラクターの場合):
新しい乱数ジェネレーターを作成します。そのシードは、現在の時刻に基づく値に初期化されます。
public Random() { this(System.currentTimeMillis()); }
同じミリ秒以内に作成された2つのランダムオブジェクトは、同じ乱数シーケンスを持ちます。
これで、シードがミリ秒単位の現在の時刻であることが確実にわかりました。また、 2番目のコンストラクターのドキュメントには次のように書かれています。
単一の長いシードを使用して、新しい乱数ジェネレーターを作成します。
public Random(long seed) { setSeed(seed); }
疑似乱数ジェネレータの状態を保持するために次のメソッドによって使用されます。
メソッドのドキュメントには次のように書かれています。setSeed
単一の長いシードを使用して、この乱数ジェネレーターのシードを設定します。setSeedの一般的な契約は、この乱数ジェネレータオブジェクトの状態を変更して、引数seedをシードとして作成されたばかりの場合とまったく同じ状態になるようにすることです。setSeedメソッドは、クラスRandomによって次のように実装されます。
synchronized public void setSeed(long seed) {
this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
haveNextNextGaussian = false;
}
クラスRandomによるsetSeedの実装では、指定されたシードの48ビットのみが使用されます。ただし、一般に、オーバーライドメソッドはlong引数の64ビットすべてをシード値として使用できます。注:シード値はAtomicLongですが、haveNextNextGaussianの正しいセマンティクスを確保するには、このメソッドを同期する必要があります。
乱数を生成するために使用される実際の方法は次のnextDouble
とおりです。
この乱数ジェネレーターのシーケンスから、次の疑似乱数で均一に分散された0.0〜1.0のdouble値を返します。
関数の実装は次のnextDouble
とおりです。
public double nextDouble() {
return (((long)next(26) << 27) + next(27))
/ (double)(1L << 53);
}
明らかにそれは機能に依存しnext
ます:
次の疑似乱数を生成します。これは他のすべてのメソッドで使用されるため、サブクラスはこれをオーバーライドする必要があります。
関数の実装は次のnext
とおりです。
synchronized protected int next(int bits) {
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int)(seed >>> (48 - bits));
}
それがあなたが探している疑似ランダム関数です。ドキュメントに記載されているように:
これは、DH Lehmerによって定義され、The Art of Computer Programming、Volume 2:Seminumerical Algorithms、section3.2.1でDonaldE. Knuthによって説明されている、線形合同の疑似乱数ジェネレータです。
ただし、これはRhinoで使用される乱数ジェネレーターのみであることに注意してください。SpidermonkeyやV8のような他の実装には、独自の疑似乱数ジェネレーターがある場合があります。