web-dev-qa-db-fra.com

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

Quelle est la différence entre Math.random() * n et Random.nextInt(n)n est un entier?

124
Gili

Voici l'explication détaillée pourquoi "Random.nextInt(n) est à la fois plus efficace et moins biaisé que Math.random() * n" du post de forums Sun que Gili a lié à:

Math.random () utilise Random.nextDouble () en interne.

Random.nextDouble () utilise Random.next () deux fois pour générer un double dont la mantisse contient des bits approximativement uniformément répartis. Il est donc uniformément réparti entre 0 et 1- (2 ^ -53).

Random.nextInt (n) utilise Random.next () moins de deux fois en moyenne. Il l’utilise une fois. Si la valeur obtenue est supérieure au multiple le plus élevé de n en dessous de MAX_INT, elle réessaie. Sinon, elle renvoie la valeur modulo n (this empêche les valeurs supérieures au multiple supérieur de n inférieur à MAX_INT de fausser la distribution), renvoyant ainsi une valeur uniformément répartie dans la plage 0 à n-1.

Avant la mise à l'échelle par 6, la sortie de Math.random () est l'une des 2 ^ 53 valeurs possibles tirées d'une distribution uniforme.

La mise à l'échelle par 6 ne modifie pas le nombre de valeurs possibles, et la conversion en un int force alors ces valeurs dans l'un des six "compartiments" (0, 1, 2, 3, 4, 5), chaque compartiment correspondant à des plages englobant soit 1501199875790165 ou 1501199875790166 des valeurs possibles (car 6 n’est pas un défenseur de 2 ^ 53). Cela signifie que pour un nombre suffisant de jets de dés (ou un dé avec un nombre de faces suffisamment grand), le dé va se montrer biaisé en faveur des seaux plus grands.

Vous allez attendre très longtemps avant de lancer les dés pour que cet effet apparaisse.

Math.random () nécessite également environ deux fois plus de traitement et est soumis à la synchronisation.

161
matt b

un autre point important est que Random.nextInt (n) est répétable puisque vous pouvez créer deux objets Random avec la valeur de départ identique. Ce n'est pas possible avec Math.random ().

27
dfa

Selon https://forums.Oracle.com/forums/thread.jspa?messageID=6594485&#6594485Random.nextInt(n) est à la fois plus efficace et moins biaisé que Math.random() * n

14
Gili

Selon cet exemple, Random.nextInt(n) a une sortie moins prévisible que Math.random () * n. Selon [un tableau trié plus rapidement qu'un tableau non trié] [1], je pense que nous pouvons dire que Random.nextInt (n) est difficile à prévoir.

usingRandomClass: time: 28 milesecond.

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));

    }

}
0
jatin Goyal