[java] Math.random () 대 Random.nextInt (int)

무엇의 차이는 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));

    }

}


답변