Accueil / javascript / 1-js / 05-data-types / 02-number / 9-random-int-min-max / solution.md

solution.md

La solution simple mais fausse

La solution la plus simple mais fausse serait de générer une valeur de min à max et de l'arrondir :

function randomInteger(min, max) {
  let rand = min + Math.random() * (max - min);
  return Math.round(rand);
}

alert( randomInteger(1, 3) );

La fonction marche, mais elle est incorrecte. La probabilité d'obtenir les valeurs min et max est deux fois inférieure à toute autre.

Si vous exécutez l'exemple ci-dessous plusieurs fois, vous verrez facilement que 2 apparaît le plus souvent.

Cela se produit car Math.round() obtient des nombres aléatoires à partir de l'intervalle 1..3 et les arrondit comme ici :

values from 1    ... to 1.4999999999  devient 1
values from 1.5  ... to 2.4999999999  devient 2
values from 2.5  ... to 2.9999999999  devient 3

Maintenant, nous pouvons clairement voir que 1 obtient deux fois moins de valeurs que 2. Et la même chose avec 3.

La bonne solution

Il existe de nombreuses solutions correctes à la tâche. L'une d'elles consiste à ajuster les limites d'intervalle. Pour garantir les mêmes intervalles, nous pouvons générer des valeurs comprises entre 0.5 et 3.5, ajoutant ainsi les probabilités requises :


function randomInteger(min, max) {
  // maintenant rand est entre (min-0.5) et (max+0.5)
  let rand = min - 0.5 + Math.random() * (max - min + 1);
  return Math.round(rand);
}

alert( randomInteger(1, 3) );

Une autre solution pourrait être d'utiliser Math.floor pour un nombre aléatoie compris entre min et max+1.


function randomInteger(min, max) {
  // ici rand est de min à (max+1)
  let rand = min + Math.random() * (max + 1 - min);
  return Math.floor(rand);
}

alert( randomInteger(1, 3) );

Maintenant, tous les intervalles sont mappés de cette façon :

values from 1  ... to 1.9999999999  devient 1
values from 2  ... to 2.9999999999  devient 2
values from 3  ... to 3.9999999999  devient 3

Tous les intervalles ont la même longueur, rendant la distribution finale uniforme.