Générer des nombres entiers aléatoires en JavaScript dans une plage spécifique ?

Comment puis-je générer des nombres entiers aléatoires entre deux variables spécifiées en JavaScript, par exemple, x = 4 et y = 8 produiraient n'importe lequel de 4, 5, 6, 7, 8 ?

Solution

Vous trouverez quelques exemples sur la page [Mozilla Developer Network][1] :

/**
 * Returns a random number between min (inclusive) and max (exclusive)
 */
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive).
 * The value is no lower than min (or the next integer greater than min
 * if min isn't an integer) and no greater than max (or the next integer
 * lower than max if max isn't an integer).
 * Using Math.round() will give you a non-uniform distribution!
 */
function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

Voici la logique derrière tout ça. C'est une simple règle de trois :

Math.random() renvoie un Nombre entre 0 (inclusif) et 1 (exclusif). Nous avons donc un intervalle comme celui-ci :

[0 .................................... 1)

Maintenant, nous voudrions un nombre entre min (inclusif) et max (exclusif) :

[0 .................................... 1)
[min .................................. max)

Nous pouvons utiliser Math.random pour obtenir le correspondant dans l'intervalle [min, max]. Mais, d'abord, nous devons factoriser un peu le problème en soustrayant min du deuxième intervalle :

[0 .................................... 1)
[min - min ............................ max - min)

Cela donne :

[0 .................................... 1)
[0 .................................... max - min)

Nous pouvons maintenant appliquer Math.random et ensuite calculer le correspondant. Choisissons un nombre aléatoire :

                Math.random()
                    |
[0 .................................... 1)
[0 .................................... max - min)
                    |
                    x (what we need)

Donc, pour trouver x, nous devrions faire :

x = Math.random() * (max - min);

N'oubliez pas d'ajouter min, afin d'obtenir un nombre dans l'intervalle [min, max] :

x = Math.random() * (max - min) + min;

C'était la première fonction de MDN. La seconde renvoie un nombre entier compris entre min et max, tous deux inclus.

Maintenant, pour obtenir des entiers, vous pouvez utiliser round, ceil ou floor.

Vous pourriez utiliser Math.round(Math.random() * (max - min)) + min, mais cela donne une distribution non uniforme. Les deux, min et max n'ont qu'environ la moitié des chances d'obtenir un résultat :

min...min+0.5...min+1...min+1.5   ...    max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘   ← Math.round()
   min          min+1                          max

Si max est exclu de l'intervalle, il a encore moins de chances d'obtenir un résultat que min.

Avec Math.floor(Math.random() * (max - min +1)) + min vous avez une distribution parfaitement égale.

min.... min+1... min+2 ... max-1... max.... max+1 (is excluded from interval)
|        |        |         |        |        |
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘   ← Math.floor()
   min     min+1               max-1    max

Vous ne pouvez pas utiliser ceil() et -1 dans cette équation parce que max a maintenant un peu moins de chance d'être lancé, mais vous pouvez aussi lancer le résultat (non désiré) min-1.

[1] : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

Commentaires (29)
function getRandomizer(bottom, top) {
    return function() {
        return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
    }
}

usage :


var rollDie = getRandomizer( 1, 6 );

var results = ""
for ( var i = 0; i
Commentaires (7)
function getRandomInt(lower, upper)
{
    //to create an even sample distribution
    return Math.floor(lower + (Math.random() * (upper - lower + 1)));

    //to produce an uneven sample distribution
    //return Math.round(lower + (Math.random() * (upper - lower)));

    //to exclude the max value from the possible values
    //return Math.floor(lower + (Math.random() * (upper - lower)));
}

Pour tester cette fonction, et ses variantes, enregistrez le HTML/JavaScript ci-dessous dans un fichier et ouvrez-le avec un navigateur. Le code produira un graphique montrant la distribution d'un million d'appels de fonction. Le code enregistrera également les cas limites, de sorte que si la fonction produit une valeur supérieure à la valeur maximale ou inférieure à la valeur minimale, vous le saurez.




        <script type="text/javascript">
        function getRandomInt(lower, upper)
        {
            //to create an even sample distribution
            return Math.floor(lower + (Math.random() * (upper - lower + 1)));

            //to produce an uneven sample distribution
            //return Math.round(lower + (Math.random() * (upper - lower)));

            //to exclude the max value from the possible values
            //return Math.floor(lower + (Math.random() * (upper - lower)));
        }

        var min = -5;
        var max = 5;

        var array = new Array();

        for(var i = 0; i 
Commentaires (0)