Qual é a diferença entre Math.random() * n
e Random.nextInt(n)
onde n
é um número inteiro?
Qual é a diferença entre Math.random() * n
e Random.nextInt(n)
onde n
é um número inteiro?
Respostas:
Aqui está a explicação detalhada de por que " Random.nextInt(n)
é mais eficiente e menos tendencioso do que Math.random() * n
" nos fóruns da Sun que Gili vinculou:
Math.random () usa Random.nextDouble () internamente.
Random.nextDouble () usa Random.next () duas vezes para gerar um dobro que possui bits aproximadamente distribuídos uniformemente em sua mantissa, portanto, é uniformemente distribuído no intervalo de 0 a 1- (2 ^ -53).
Random.nextInt (n) usa Random.next () menos do que o dobro da média - ele o usa uma vez e, se o valor obtido estiver acima do múltiplo mais alto de n abaixo de MAX_INT, ele tentará novamente, caso contrário, retornará o valor módulo n (este impede que os valores acima do múltiplo mais alto de n abaixo de MAX_INT incline a distribuição), retornando um valor uniformemente distribuído no intervalo de 0 a n-1.
Antes da escala de 6, a saída de Math.random () é um dos 2 ^ 53 valores possíveis extraídos de uma distribuição uniforme.
O escalonamento por 6 não altera o número de valores possíveis e a conversão para um int força esses valores a um dos seis 'buckets' (0, 1, 2, 3, 4, 5), cada bucket correspondente a intervalos que abrangem 1501199875790165 ou 1501199875790166 dos valores possíveis (como 6 não é um disvisor de 2 ^ 53). Isso significa que, para um número suficiente de jogadas de dados (ou um dado com um número suficientemente grande de lados), o dado se mostrará inclinado para os baldes maiores.
Você estará esperando muito tempo rolando dados para que esse efeito apareça.
Math.random () também requer aproximadamente o dobro do processamento e está sujeito a sincronização.
6
com 5
em um cubo dados: será "5-tendenciosa". Você pode jogar os dados algumas vezes antes de perceber que algo está errado com os dados. Você é forçado a realizar um exame completo extremamente sofisticado antes de perceber que algo está errado com um gerador aleatório.
De acordo com https://forums.oracle.com/forums/thread.jspa?messageID=6594485�, Random.nextInt(n)
é mais eficiente e menos tendencioso do queMath.random() * n
De acordo com este exemplo Random.nextInt(n)
, a saída é menos previsível do que Math.random () * n. De acordo com [matriz ordenada mais rapidamente que uma matriz não classificada] [1], acho que podemos dizer que Random.nextInt (n) é difícil de prever .
usingRandomClass: time: 328 milhasecond.
usingMathsRandom: time: 187 milesecond.
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()