무엇의 차이는 Math.random() * n
하고 Random.nextInt(n)
어디 n
정수 무엇입니까?
답변
다음은 Gili가 링크 한 Sun 포럼 게시물에서 ” 보다 더 효율적이고 편향이 적은 이유”에 대한 자세한 설명 입니다 .Random.nextInt(n)
Math.random() * n
Math.random ()은 내부적으로 Random.nextDouble ()을 사용합니다.
Random.nextDouble ()은 Random.next ()를 두 번 사용하여 가수에 대략 균일하게 분포 된 비트를 갖는 double을 생성하므로 0에서 1- (2 ^ -53) 범위로 균일하게 분포됩니다.
Random.nextInt (n)은 평균에서 두 번 미만인 Random.next ()를 사용합니다. 한 번만 사용합니다. 획득 한 값이 MAX_INT 아래의 n의 가장 높은 배수보다 높으면 다시 시도하고 그렇지 않으면 modulo n 값을 반환합니다 (이 값은 MAX_INT 아래의 n의 가장 높은 배수를 초과하는 값이 분포를 왜곡하지 않도록 방지) 0에서 n-1 범위로 균일하게 분포 된 값을 반환합니다.
6으로 스케일하기 전에 Math.random ()의 출력은 균일 분포에서 도출 된 2 ^ 53 개의 가능한 값 중 하나입니다.
6으로 스케일링해도 가능한 값의 개수가 변경되지 않고 int로 캐스팅하면이 값을 6 개의 버킷 (0, 1, 2, 3, 4, 5) 중 하나로 강제합니다. 각 버킷은 다음 중 하나를 포함하는 범위에 해당합니다. 가능한 값 중 1501199875790165 또는 1501199875790166 (6은 2 ^ 53의 제수가 아님). 이것은 충분한 수의 다이스 롤 (또는 충분히 많은 수의 측면을 가진 다이)에 대해 다이가 더 큰 버킷을 향해 편향되어 있음을 나타냅니다.
이 효과가 나타날 때까지 매우 오랜 시간 동안 주사위를 굴릴 것입니다.
Math.random ()도 약 두 배의 처리가 필요하며 동기화 될 수 있습니다.
답변
또 다른 중요한 점은 Random.nextInt (n)은 동일한 시드로 두 개의 Random 객체를 만들 수 있기 때문에 반복 가능하다는 것 입니다. Math.random ()에서는 불가능합니다.
답변
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));
}
}