Obtenir du hasard d’un ordinateur, qui a été conçu dès le début pour être le plus déterministe possible, est certainement une des plus grandes difficultés en programmation. Ce n’est pas pour rien que les entreprises qui doivent créer des certificats recourent à des périphériques spécifiques pour générer de l’entropie (station météo, manette à secouer, etc.)
Lorsque vous manipulez la classe System.Random, faites bien attention à ne pas trop manipuler le nombre que vous obtenez. Prenons le code ci-dessous : vous demandez une valeur entre 0 et 999, et l’utilisez telle quelle.
Pas de problème, la répartition est linéaire :
Mais imaginons maintenant que, pour une raison ou pour une autre, vous montiez à un million la taille du plus grand entier demandé, car votre algorithme avait besoin de deux fois une valeur sur trois chiffres. C’est plutôt une bonne idée à la base de réduire les appels à la fonction de génération de pseudo-hasard (voire une très bonne idée si vous utilisez une fonction de hasard de classe cryptographique, qui prendra beaucoup plus de temps). Mais voila, vous n’avez pas réalisé proprement le code pour récupérer les trois derniers chiffres, et vous avez introduit une perte de précision :
Le résultat, du point de vue du hasard, est catastrophique, à savoir que certaines valeurs sont bien plus représentées que d’autres :
Evidemment, si c’est un jeu qui utilise cette fonction pour introduire du bruit dans les déplacements d’un bonhomme par exemple, le déplacement sera un peu plus erratique que prévu… Dans certains cas (utilisation pour la direction au degré près), ça passe, dans d’autres (utilisation de l’aspect pair / impair pour une décision), c’est une catastrophe, car le hasard sera complètement biaisé.
Pour ne pas introduire de perte de précision, il faut repartir de la valeur choisie au hasard et lui soustraire la partie haute :
Ce qui nous amène à nouveau à une répartition propre des nombres :
Conclusion : attention quand on manipule des nombres au hasard. Non seulement des classes comme Random ne donnent que du pseudo-hasard (bien que plutôt bien équilibré en .NET), mais en plus les manipulations de chiffres après doivent être soigneusement étudiées pour ne pas perdre de précision, car dans ce cas, l’impact sur la distribution statistique peut être extrêmement fort.