Attention au Random !

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.

image

Pas de problème, la répartition est linéaire :

image

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 :

image

Le résultat, du point de vue du hasard, est catastrophique, à savoir que certaines valeurs sont bien plus représentées que d’autres :

image

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 :

image

Ce qui nous amène à nouveau à une répartition propre des nombres :

image

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.

About JP Gouigoux

Jean-Philippe Gouigoux est Architecte Logiciel, MVP Connected Systems Developer. Il intervient régulièrement à l'Université de Bretagne Sud ainsi qu'à l'Agile Tour. Plus de détails sur la page "Curriculum Vitae" de ce blog.
This entry was posted in .NET, C#. Bookmark the permalink.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha Captcha Reload