Was ist der Unterschied zwischen Math.random() * n
und Random.nextInt(n)
wo n
ist eine ganze Zahl?
Was ist der Unterschied zwischen Math.random() * n
und Random.nextInt(n)
wo n
ist eine ganze Zahl?
Antworten:
Hier ist die detaillierte Erklärung, warum " Random.nextInt(n)
sowohl effizienter als auch weniger voreingenommen ist als Math.random() * n
" aus dem Beitrag der Sun-Foren, mit dem Gili verlinkt hat:
Math.random () verwendet intern Random.nextDouble ().
Random.nextDouble () verwendet Random.next () zweimal, um ein Double zu generieren, dessen Mantisse ungefähr gleichmäßig verteilte Bits enthält, sodass es gleichmäßig im Bereich von 0 bis 1- (2 ^ -53) verteilt ist.
Random.nextInt (n) verwendet Random.next () im Durchschnitt weniger als zweimal - es wird einmal verwendet, und wenn der erhaltene Wert über dem höchsten Vielfachen von n unter MAX_INT liegt, wird es erneut versucht, andernfalls wird der Wert modulo n (this) zurückgegeben verhindert, dass die Werte über dem höchsten Vielfachen von n unter MAX_INT die Verteilung verzerren), wodurch ein Wert zurückgegeben wird, der gleichmäßig im Bereich von 0 bis n-1 verteilt ist.
Vor der Skalierung um 6 ist die Ausgabe von Math.random () einer von 2 ^ 53 möglichen Werten, die aus einer gleichmäßigen Verteilung gezogen werden.
Durch Skalieren mit 6 wird die Anzahl der möglichen Werte nicht geändert, und durch Umwandeln in ein int werden diese Werte in einen von sechs "Buckets" (0, 1, 2, 3, 4, 5) gezwungen, wobei jeder Bucket den Bereichen entspricht, die beide umfassen 1501199875790165 oder 1501199875790166 der möglichen Werte (da 6 kein Disvisor von 2 ^ 53 ist). Dies bedeutet, dass sich für eine ausreichende Anzahl von Würfeln (oder einen Würfel mit einer ausreichend großen Anzahl von Seiten) der Würfel in Richtung der größeren Eimer vorgespannt zeigt.
Sie werden sehr lange darauf warten, dass dieser Effekt angezeigt wird.
Math.random () erfordert ebenfalls etwa die doppelte Verarbeitung und unterliegt der Synchronisation.
6
durch 5
einen Würfelwürfel: Es wird "5-voreingenommen" sein. Sie können die Würfel ein paar Mal werfen, bevor Sie feststellen, dass etwas mit den Würfeln nicht stimmt. Sie sind gezwungen, eine äußerst anspruchsvolle gründliche Prüfung durchzuführen, bevor Sie feststellen, dass mit einem Zufallsgenerator etwas nicht stimmt.
Laut https://forums.oracle.com/forums/thread.jspa?messageID=6594485龵 Random.nextInt(n)
ist dies sowohl effizienter als auch weniger voreingenommen alsMath.random() * n
Nach diesem Beispiel Random.nextInt(n)
hat weniger vorhersehbare Ausgabe als Math.random () * n. Laut [sortiertes Array schneller als ein unsortiertes Array] [1] können wir sagen, dass Random.nextInt (n) schwer vorherzusagen ist .
usingRandomClass: Zeit: 328 Meilensekunde.
usingMathsRandom: Zeit: 187 Meilensekunde.
package javaFuction;
import java.util.Random;
public class RandomFuction
{
static int array[] = new int[9999];
static long sum = 0;
public static void usingMathsRandom() {
for (int i = 0; i < 9999; i++) {
array[i] = (int) (Math.random() * 256);
}
for (int i = 0; i < 9999; i++) {
for (int j = 0; j < 9999; j++) {
if (array[j] >= 128) {
sum += array[j];
}
}
}
}
public static void usingRandomClass() {
Random random = new Random();
for (int i = 0; i < 9999; i++) {
array[i] = random.nextInt(256);
}
for (int i = 0; i < 9999; i++) {
for (int j = 0; j < 9999; j++) {
if (array[j] >= 128) {
sum += array[j];
}
}
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
usingRandomClass();
long end = System.currentTimeMillis();
System.out.println("usingRandomClass " + (end - start));
start = System.currentTimeMillis();
usingMathsRandom();
end = System.currentTimeMillis();
System.out.println("usingMathsRandom " + (end - start));
}
}
Math.random()