web-dev-qa-db-ja.com

Math.random()対Random.nextInt(int)

Math.random() * nRandom.nextInt(n)の違いは何ですか?nは整数ですか?

124
Gili

詳細な説明 GiliがリンクしたSunフォーラムの投稿からの「Random.nextInt(n)Math.random() * nよりも効率的で偏りが少ない理由」:

Math.random()は、内部的にRandom.nextDouble()を使用します。

Random.nextDouble()は、Random.next()を2回使用して、仮数部にほぼ均一に分布したビットを持つdoubleを生成します。したがって、0〜1-(2 ^ -53)の範囲に均一に分布します。

Random.nextInt(n)は、平均して2回未満のRandom.next()を使用します。1回使用します。取得した値がMAX_INT未満のnの最大倍数を超える場合は、再試行します。 MAX_INT未満のnの最大倍数を超える値が分布を歪ませるのを防ぐため、0〜n-1の範囲で均一に分布する値を返します。

6でスケーリングする前は、Math.random()の出力は、均一な分布から得られる2 ^ 53の可能な値の1つです。

6でスケーリングしても、可能な値の数は変わりません。intにキャストすると、これらの値は6つの「バケット」(0、1、2、3、4、5)のいずれかになります。各バケットは、 1501199875790165または1501199875790166の可能な値(6は2 ^ 53の約数ではないため)。これは、十分な数のダイスロール(または十分に多数の側面を持つダイス)の場合、ダイスはより大きなバケットに向かってバイアスされることを示します。

あなたはこの効果が現れるのを非常に長い時間サイコロを待っています。

Math.random()も約2倍の処理を必要とし、同期の対象となります。

161
matt b

もう1つの重要な点は、Random.nextInt(n)が反復可能であることです。これは、sameシードを使用して2つのRandomオブジェクトを作成できるためです。これはMath.random()では不可能です。

27
dfa

https://forums.Oracle.com/forums/thread.jspa?messageID=6594485&#6594485Random.nextInt(n)によると、Math.random() * nよりも効率的で偏りが少ない

14
Gili

この例によると、Random.nextInt(n)は、Math.random()* nよりも予測可能な出力が少なくなります。 [ソートされていない配列よりもソートされた配列] [1]によると、Random.nextInt(n)は予測困難と言えると思います。

usingRandomClass:time:28マイル秒。

usingMathsRandom:time: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));

    }

}
0
jatin Goyal