Jaka jest różnica między Math.random() * n
i Random.nextInt(n)
gdzie n
jest liczba całkowita?
Jaka jest różnica między Math.random() * n
i Random.nextInt(n)
gdzie n
jest liczba całkowita?
Odpowiedzi:
Oto szczegółowe wyjaśnienie, dlaczego „ Random.nextInt(n)
jest zarówno bardziej wydajne, jak i mniej stronnicze niż Math.random() * n
” z postu na forach firmy Sun, do którego prowadzi Gili:
Math.random () używa Random.nextDouble () wewnętrznie.
Random.nextDouble () używa Random.next () dwukrotnie, aby wygenerować double, który ma w przybliżeniu równomiernie rozłożone bity w mantysie, więc jest równomiernie rozłożony w zakresie od 0 do 1- (2 ^ -53).
Random.nextInt (n) używa Random.next () średnio mniej niż dwa razy - używa go raz, a jeśli uzyskana wartość jest powyżej najwyższej wielokrotności n poniżej MAX_INT, próbuje ponownie, w przeciwnym razie zwraca wartość modulo n (to zapobiega przekrzywianiu rozkładu wartości powyżej najwyższej wielokrotności n poniżej wartości MAX_INT), w związku z czym zwraca wartość, która jest równomiernie rozłożona w zakresie od 0 do n-1.
Przed skalowaniem o 6 wynik funkcji Math.random () jest jedną z 2 ^ 53 możliwych wartości pobranych z rozkładu równomiernego.
Skalowanie o 6 nie zmienia liczby możliwych wartości, a rzutowanie na int następnie wymusza te wartości w jednym z sześciu „przedziałów” (0, 1, 2, 3, 4, 5), z których każdy odpowiada zakresom obejmującym albo 1501199875790165 lub 1501199875790166 z możliwych wartości (ponieważ 6 nie jest doradcą 2 ^ 53). Oznacza to, że przy wystarczającej liczbie rzutów kośćmi (lub kości z dostatecznie dużą liczbą boków), kość okaże się odchylona w kierunku większych koszy.
Będziesz bardzo długo czekać, aż ten efekt się pojawi.
Math.random () również wymaga około dwukrotnie większego przetwarzania i podlega synchronizacji.
6
ze 5
na sześcian: będzie to „5-tendencyjne”. Możesz rzucić kostką kilka razy, zanim zauważysz, że coś jest nie tak z kostką. Jesteś zmuszony przeprowadzić niezwykle wyrafinowane, dokładne badanie, zanim zauważysz, że coś jest nie tak z generatorem losowym.
Według https://forums.oracle.com/forums/thread.jspa?messageID=6594485龵 Random.nextInt(n)
jest zarówno bardziej wydajny, jak i mniej stronniczy niżMath.random() * n
Zgodnie z tym przykładem Random.nextInt(n)
ma mniej przewidywalne wyniki niż Math.random () * n. Zgodnie z [posortowana tablica szybciej niż nieposortowana tablica] [1] Myślę, że możemy powiedzieć, że Random.nextInt (n) jest trudna do przewidzenia .
usingRandomClass: time: 328 milecond.
usingMathsRandom: time: 187 milekund.
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()