122 votes

A quel point Math.random de JavaScript est-il aléatoire ?

Pendant 6 ans, j'ai eu un générateur de nombres aléatoires sur mon site web. Pendant longtemps, il a été le premier ou le deuxième résultat de Google pour "générateur de nombres aléatoires" et a été utilisé pour décider de dizaines, voire de centaines de concours et de tirages au sort sur des forums de discussion et des blogs (je le sais parce que je vois les référents dans mes journaux Web et j'ai l'habitude d'aller y jeter un œil).

Aujourd'hui, quelqu'un m'a envoyé un e-mail pour me dire ce n'est peut-être pas aussi aléatoire que je le pensais. Elle a essayé de générer de très grands nombres aléatoires (par exemple, entre 1 et 10000000000000000000) et a constaté qu'ils contenaient presque toujours le même nombre de chiffres. En effet, j'ai enveloppé la fonction dans une boucle afin de pouvoir générer des milliers de nombres et, bien sûr, pour de très grands nombres, la variation n'était que d'environ 2 ordres de grandeur.

Pourquoi ?

Voici la version en boucle, pour que vous puissiez l'essayer par vous-même :

http://andrew.hedges.name/experiments/random/randomness.html

Il comprend à la fois une mise en œuvre simple tirée de l'application Réseau de développeurs Mozilla et du code datant de 1997 que j'ai piqué sur une page web qui n'existe plus (Paul Houle's "Central Randomizer 1.3"). Voir la source pour voir comment chaque méthode fonctionne.

J'ai lu aquí y ailleurs à propos de Mersenne Twister. Ce qui m'intéresse, c'est de savoir pourquoi il n'y aurait pas une plus grande variation dans les résultats de JavaScript. Math.random fonction. Merci !

0 votes

"sarnath'd" comme dans, battu au poing, ou dans ce cas, la réponse.

6 votes

Si vous cherchez la réponse à la question posée dans le titre, voir stackoverflow.com/questions/2344312/

187voto

Quentin Points 325526

Compte tenu de nombres compris entre 1 et 100.

  • 9 ont 1 chiffre (1-9)
  • 90 ont 2 chiffres (10-99)
  • 1 a 3 chiffres (100)

Étant donné les nombres entre 1 et 1000.

  • 9 ont 1 chiffre
  • 90 ont 2 chiffres
  • 900 ont 3 chiffres
  • 1 a 4 chiffres

et ainsi de suite.

Ainsi, si vous en sélectionnez quelques-uns au hasard, la grande majorité des nombres sélectionnés auront le même nombre de chiffres, car la grande majorité des valeurs possibles ont le même nombre de chiffres.

12 votes

Votre idée d'une distribution parfaite et régulière du hasard est intrigante...

21 votes

@R.Pate - numéro aléatoire génération n'est pas d'une grande utilité si elle n'est pas distribuée uniformément sur une longue échelle.

3 votes

Relisez. @David ne fait qu'indiquer le type de nombres qui se trouvent entre les limites, et non le résultat de la sélection de N nombres aléatoires. J'admets que le titre est trompeur.

57voto

jwoolard Points 1905

Vos résultats sont en fait attendus. Si les nombres aléatoires sont distribués uniformément dans un intervalle de 1 à 10^n, alors vous vous attendez à ce qu'environ 9/10 des nombres aient n chiffres, et 9/100 à ce qu'ils aient n-1 chiffres.

8 votes

Exactement. La distribution du nombre de chiffres sera vraisemblablement asymétrique. En revanche, la distribution du logarithme du nombre de chiffres devrait être uniforme.

45voto

Christian Points 6060

Il existe différents types de hasard. Math.random vous donne une distribution uniforme des nombres.

Si vous voulez des ordres de grandeur différents, je vous suggère d'utiliser une fonction exponentielle pour créer ce que l'on appelle un distribution en loi de puissance :

function random_powerlaw(mini, maxi) {
    return Math.ceil(Math.exp(Math.random()*(Math.log(maxi)-Math.log(mini)))*mini)
}

Cette fonction devrait vous donner à peu près le même nombre de nombres à 1 chiffre que de nombres à 2 chiffres et que de nombres à 3 chiffres.

Il existe également d'autres distributions pour les nombres aléatoires comme la distribution normale (également appelée distribution gaussienne).

0 votes

Avec cet algorithme, je mets le minimum = 1 y el maximum = 10 et il arrivait parfois que l'on ait 11 ans en conséquence. Vous vouliez probablement utiliser Math.floor au lieu de Math.round

1 votes

Pourquoi cela fonctionne-t-il ? Transforme-t-il la distribution uniforme en distribution exponentielle ?

0 votes

@shinzou J'ai demandé sur math.stackexchange et j'ai obtenu une formule légèrement différente comme réponse. J'ai modifié le code pour refléter la formule dérivée mathématiquement de math.stackexchange.

21voto

Arafangion Points 5650

Ça me semble parfaitement aléatoire ! (Indice : ça dépend du navigateur).

Personnellement, je pense que mon implémentation serait meilleure, bien que je l'aie volée de XKCD qui doit TOUJOURS être reconnu :

function random() {
  return 4; // Chosen by a fair dice throw. Guaranteed to be random.
}

19 votes

+1 pour avoir mentionné que ça dépend du navigateur, -1 pour avoir emprunté xkcd sans faire de lien.

0 votes

Nécessaire ou non, puisque c'est xkcd, il est attribué :)

2 votes

OT : Je suis surpris et heureux que "XKCD" soit la réponse à une question du Challenge universitaire cette semaine :D

18voto

jj1bdx Points 563

L'article suivant explique comment math.random() dans les principaux navigateurs Web est (non) sécurisé : "Le suivi temporaire de l'utilisateur dans les principaux navigateurs et les fuites et attaques d'informations interdomaines leakage and attacks" par Amid Klein (2008) . Il n'est pas plus puissant que les fonctions PRNG intégrées typiques de Java ou de Windows.

D'autre part, la mise en œuvre d'un SFMT de période 2^19937-1 nécessite 2496 octets de l'état interne maintenu pour chaque séquence PRNG. Certaines personnes peuvent considérer cela comme un coût impardonnable.

1 votes

+1 : L'article mentionné est excellent, bien au-delà de ce que la question originale était.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X