Génération aléatoire d’un nombre entier compris dans un intervalle

Comment générer aléatoirement un nombre entier compris dans un intervalle, c'est-à-dire entre des valeurs minimale et maximale ? La solution qui vient spontanément à l'esprit (min + Math.round ((max -1) * Math.random ())) n'est pas correcte, car elle n'assure pas la représentativité statistique équitable (équiprobabilité) de tous les entiers possibles.
Par exemple, la répétition de 1 000 tirages d'une valeur dans l'intervalle [3, 9] permet de dégager les probabilités d'occurrence par valeur suivantes :
Génération aléaoitre d'un entier compris dans un intervalle (mauvais)
Pourquoi ce problème, et comment y remédier ?

La solution

Comme le graphique présenté permet de le constater, l'application de la solution qui vient spontanément à l'esprit conduit à une sous-représentation statistique de la valeur 3 ; plus généralement, la probabilité de la valeur minimale de l'intervalle est minorée.
La raison est que le code s'appuie sur Math.round (), qui va arrondir à 0 une valeur dans [0, 0.5[, à 1 une valeur dans [0.5, 1.5[, à 2 une valeur dans [1.5, 2.5[ etc. Le premier de ces intervalles à une amplitude de presque 0.5, tandis que les intervalles suivants ont une amplitude de presque 1.0. Bref, quand une valeur aléatoire (max -1) * Math.random () est générée, elle a deux fois moins de chances d'être arrondie à 0 que d'être arrondie à tout entier au-delà.
Il faut donc s'assurer que Math.round () sera appelée à arrondir des valeurs d'un intervalle d'amplitude de (presque) 1.0.

Le code JavaScript

En JavaScript, la solution se traduit par le code suivant :
function randomInt (min, max) {
	return (min + Math.floor ((max - min + 1) * Math.random ()));
}

L'exemple

Cliquez ici pour accéder à une page de test minimaliste. Vous pourrez visualiser le code et le récupérer pour travailler avec.

Les maths

Il s'agit d'éviter d'utiliser Math.round () pour arrondir une valeur dans [0.0, 0.5[ à 0. A la place, il faut utiliser Math.floor () pour arrondir une valeur dans [0.0, 1.0[ à 0.
Pour reprendre l'exemple initial, la répétition de 1 000 tirages d'une valeur dans l'intervalle [3, 9] à l'aide de la solution permet de dégager les probabilités d'occurrence par valeur suivantes :
Génération aléaoitre d'un entier compris dans un intervalle (bon)
On constate l'équiprobabilité des valeurs entières dans l'intervalle [3, 9].
Génération aléatoire d’un nombre entier compris dans un intervalle