Il existe quelques exemples sur le site Réseau de développeurs Mozilla page :
/**
* 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 Number
entre 0 (inclusif) et 1 (exclusif). Nous avons donc un intervalle comme celui-ci :
[0 .................................... 1)
Maintenant, nous aimerions un nombre entre min
(inclus) et max
(exclusif) :
[0 .................................... 1)
[min .................................. max)
Nous pouvons utiliser le 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 second intervalle :
[0 .................................... 1)
[min - min ............................ max - min)
Cela donne :
[0 .................................... 1)
[0 .................................... max - min)
Nous pouvons maintenant appliquer Math.random
puis calculer le correspondant. Choisissons un nombre au hasard :
Math.random()
|
[0 .................................... 1)
[0 .................................... max - min)
|
x (what we need)
Donc, afin de trouver x
nous le ferions :
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
y max
les deux inclus.
Maintenant, pour obtenir des entiers, vous pouvez utiliser round
, ceil
o floor
.
Vous pourriez utiliser Math.round(Math.random() * (max - min)) + min
ce qui donne cependant une distribution non uniforme. Les deux, min
y max
n'ont qu'environ la moitié des chances de rouler :
min...min+0.5...min+1...min+1.5 ... max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘ ← Math.round()
min min+1 max
Avec max
exclu de l'intervalle, il a encore moins de chance de rouler 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()
y -1
dans cette équation car max
a maintenant un peu moins de chance d'être lancé, mais vous pouvez lancer le (indésirable) min-1
résultat aussi.
2 votes
Voici un résumé utile : gist.github.com/kerimdzhanov/7529623
15 votes
Remarque : pour ceux qui utilisent npm et recherchent une solution rapide, fiable et prête à l'emploi, il y a lodash.random qui peut être facilement exigé avec un encombrement très faible (il importera juste la méthode elle-même et non le lodash entier).
0 votes
Si elle doit être crypto sécurisée developer.mozilla.org/fr/US/docs/Web/API/RandomSource/