¿Cuál es la diferencia entre Math.random() * n
y Random.nextInt(n)
dónde n
está un número entero?
¿Cuál es la diferencia entre Math.random() * n
y Random.nextInt(n)
dónde n
está un número entero?
Respuestas:
Aquí está la explicación detallada de por qué " Random.nextInt(n)
es más eficiente y menos sesgado que Math.random() * n
" de la publicación en los foros de Sun a la que Gili se vinculó:
Math.random () usa Random.nextDouble () internamente.
Random.nextDouble () usa Random.next () dos veces para generar un doble que tiene bits distribuidos aproximadamente uniformemente en su mantisa, por lo que se distribuye uniformemente en el rango de 0 a 1- (2 ^ -53).
Random.nextInt (n) usa Random.next () menos de dos veces en promedio, lo usa una vez, y si el valor obtenido está por encima del múltiplo más alto de n por debajo de MAX_INT lo intenta nuevamente; de lo contrario, devuelve el valor módulo n (esto evita que los valores por encima del múltiplo más alto de n por debajo de MAX_INT sesguen la distribución), por lo que devuelve un valor que se distribuye uniformemente en el rango de 0 a n-1.
Antes de escalar en 6, la salida de Math.random () es uno de los 2 ^ 53 posibles valores extraídos de una distribución uniforme.
Escalar en 6 no altera el número de valores posibles, y la conversión a un int obliga a estos valores a uno de los seis 'cubos' (0, 1, 2, 3, 4, 5), cada cubo corresponde a rangos que abarcan 1501199875790165 o 1501199875790166 de los posibles valores (ya que 6 no es un supervisor de 2 ^ 53). Esto significa que para un número suficiente de tiradas de dados (o un dado con un número suficientemente grande de lados), el dado se mostrará sesgado hacia los cubos más grandes.
Esperarás mucho tiempo tirando dados para que aparezca este efecto.
Math.random () también requiere aproximadamente el doble del procesamiento y está sujeto a sincronización.
6
con 5
en un cubo de dados: será "5 parcial". Puedes lanzar los dados un par de veces antes de notar que algo está mal con los dados. Se ve obligado a realizar un examen exhaustivo extremadamente sofisticado antes de notar que algo anda mal con un generador aleatorio.
De acuerdo con https://forums.oracle.com/forums/thread.jspa?messageID=6594485龵 Random.nextInt(n)
es más eficiente y menos sesgado queMath.random() * n
De acuerdo con este ejemplo, Random.nextInt(n)
tiene una salida menos predecible que Math.random () * n. Según [matriz ordenada más rápido que una matriz sin clasificar] [1] creo que podemos decir que Random.nextInt (n) es difícil de predecir .
usingRandomClass: tiempo: 328 millas por segundo.
usingMathsRandom: tiempo: 187 millas por segundo.
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()