Яка різниця між Math.random() * nі Random.nextInt(n)де nціле число?
Яка різниця між Math.random() * nі Random.nextInt(n)де nціле число?
Відповіді:
Ось детальне пояснення того, чому "публікація Random.nextInt(n)є і більш ефективною, і менш упередженою, ніж Math.random() * n" з публікації на форумах Sun, до якої посилається Гілі:
Math.random () використовує Random.nextDouble () внутрішньо.
Random.nextDouble () використовує Random.next () двічі, щоб генерувати подвійний, який має приблизно рівномірно розподілені біти у своїй мантісі, тому він рівномірно розподілений у діапазоні від 0 до 1- (2 ^ -53).
Random.nextInt (n) використовує Random.next () менше ніж удвічі менше - він використовує його один раз, і якщо отримане значення вище найвищого кратного n нижче MAX_INT, воно намагається знову, інакше повертає значення modulo n (це запобігає значенню вище найвищого кратного n нижче MAX_INT скасування розподілу), тому повертає значення, яке рівномірно розподіляється в діапазоні від 0 до n-1.
До масштабування на 6 вихід Math.random () є одним із 2 ^ 53 можливих значень, отриманих з рівномірного розподілу.
Масштабування на 6 не змінює кількість можливих значень, а кастинг до int потім змушує ці значення в одне з шести "відер" (0, 1, 2, 3, 4, 5), кожне відро, відповідне діапазонам, що охоплюють або 1501199875790165 або 1501199875790166 можливих значень (оскільки 6 не є дисизором 2 ^ 53). Це означає, що для достатньої кількості рулонів кісток (або штампу з достатньо великою кількістю боків) матриця покаже себе упередженою до великих ковшів.
Ви дуже довго будете чекати, коли цей ефект проявиться.
Math.random () також вимагає приблизно двічі обробки та підлягає синхронізації.
6з 5на кістки кубі: це буде «5-упередженим». Ви можете кинути кістки кілька разів, перш ніж помітите, що з кісткою щось не так. Ви змушені провести надзвичайно складне ретельне обстеження, перш ніж помітите, що з випадковим генератором щось не так.
Згідно з https://forums.oracle.com/forums/thread.jspa?messageID=6594485龵 Random.nextInt(n) є ефективнішим і менш упередженим, ніжMath.random() * n
Відповідно до цього прикладу Random.nextInt(n)має менш передбачуваний вихід, ніж Math.random () * n. Відповідно до [відсортований масив швидше, ніж несортований масив] [1] Я думаю, що ми можемо сказати, що Random.nextInt (n) важко передбачити .
usingRandomClass: час: 328 миль секунди.
usingMathsRandom: час: 187 миль секунди.
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()