Ich schaute durch das Rhino source code, um herauszufinden, welche Pseudozufallsfunktion sie verwenden. Offenbar sind sie fall back zu der Math.random
Funktion definiert in der Java standard library.
Die Dokumentation für Math.random
sagt:
Gibt einen double-Wert mit einem positiven Vorzeichen, die größer oder gleich 0,0 und weniger als 1,0. Zurückgegebene Werte werden pseudozufällig mit (annähernd) gleichförmiger Verteilung aus diesem Bereich gewählt.
Wenn diese Methode zuerst genannt wird, erzeugt es einen einzigen neuen Pseudo-Zufallszahlengenerator, genau wie durch den Ausdruck
new java.util.Random
Dieser neue Pseudo-Zufallszahlengenerator für alle Anrufe danach verwendet wird, zu dieser Methode und wird nirgendwo sonst verwendet.
Diese Methode wird ordnungsgemäß synchronisiert, um die korrekte Verwendung durch mehr als einen Thread zu ermöglichen. Wenn jedoch viele Threads Pseudozufallszahlen mit einer großen Rate erzeugen müssen, kann dies die Konkurrenz für jeden Thread reduzieren, um seinen eigenen Pseudozufallszahlengenerator zu haben.
So überprüfte ich die Dokumentation für java.util.Random
und gefunden this (für den Standard-Konstruktor):
Erstellt einen neuen Zufallszahlengenerator. Sein Samen wird auf einen Wert initialisiert, basierend auf der aktuellen Zeit:
public Random() { this(System.currentTimeMillis()); }
zwei zufällige Objekte innerhalb derselben Millisekunde erstellt wird die gleiche Folge von Zufallszahlen haben.
So jetzt wissen wir sicher, dass der Seed die aktuelle Zeit in Millisekunden ist. Auch die Dokumentation der second constructor sagt:
einen neuen Zufallszahlengenerator Erzeugt einen einzigen langen Samen mit:
public Random(long seed) { setSeed(seed); }
nach Methode Verwendete neben hält den Zustand der Pseudo-Zufallszahlen Generator.
Die documentation für die setSeed
Methode sagt:
den Samen dieser Zufallszahlengenerator Legt einen einzigen langen Samen verwendet. Der allgemeine Vertrag von setSeed besteht darin, dass er den Zustand dieses Zufallsgeneratorobjekts so ändert, dass es sich in genau demselben Zustand befindet, als wenn es gerade mit dem Argument seed als Seed erzeugt worden wäre. Das Verfahren wird durch setSeed Klasse Zufalls wie folgt implementiert:
synchronized public void setSeed(long seed) {
this.seed = (seed^0x5DEECE66DL) & ((1L << 48) - 1);
haveNextNextGaussian = false;
}
Die Umsetzung setSeed nach Klasse Zufalls geschieht nur 48 Bits des gegebenen Saatgut verwendet. Im Allgemeinen kann eine überschreibende Methode jedoch alle 64 Bits des langen Arguments als Startwert verwenden.Hinweis: Obwohl der Startwert eine AtomicLong ist, muss diese Methode dennoch synchronisiert werden, um die korrekte Semantik von haveNextNextGaussian zu gewährleisten.
Die actual method verwendet, um die Zufallszahl zu erzeugen, ist nextDouble
:
Liefert die nächste Pseudo-Zufalls gleichmäßig doppelten Wert zwischen 0,0 und 1,0 von dieser Zufallszahl-Generator-Sequenz verteilt sind.
Die Umsetzung der nextDouble
Funktion ist wie folgt:
public double nextDouble() {
return (((long)next(26) << 27) + next(27))
/(double)(1L << 53);
}
Offensichtlich es depends auf der next
Funktion:
erzeugt die nächste Pseudo-Zufallszahl. Die Unterklasse sollte dies überschreiben, da dies von allen anderen Methoden verwendet wird.
Die Umsetzung der next
Funktion ist wie folgt:
synchronized protected int next(int bits) {
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int)(seed >>> (48 - bits));
}
Das ist die Pseudozufallsfunktion ist für Sie suchen.
Dies ist ein linearer kongruenter Pseudozufallszahlengenerator, wie von DH Lehmer definiert und von Donald E. Knuth in The Art of Computer Programming, Volume 2 beschrieben: Wie es in der Dokumentation gesagt Seminumerical Algorithmen, Abschnitt 3.2. 1.
Beachten Sie jedoch, dass dies nur der von Rhino verwendete Zufallsgenerator ist. Andere Implementierungen wie Spidermonkey und V8 können ihre eigenen Pseudozufallszahlengeneratoren haben.
Der ganze Punkt von 'Math.random()' ist, dass Sie es nicht vorhersagen können (zumindest nicht ohne große Schwierigkeit). –
Gibt es jemanden, der die Quelle für 'v8' liest, um uns eine definitive Antwort zu geben? – TiansHUo
@TiansHUo - Ich las den Quellcode von Rhino und beantwortete die Frage basierend auf dem, was ich gelesen habe: http://StackOverflow.com/a/13303029/783743 –