web-dev-qa-db-fra.com

A quel point JavaScript est-il mathématique?

Pendant 6 ans, j'ai eu un générateur de nombres aléatoires page sur mon site web. Pendant longtemps, c’était le premier ou le deuxième résultat de "générateur de nombres aléatoires" sur Google. Il a été utilisé pour choisir des dizaines, voire des centaines de concours et de dessins sur des forums de discussion et des blogs (je sais journaux Web et vont généralement jeter un coup d’œil).

Aujourd’hui, une personne m’a envoyé un mail pour me dire ce n’est peut-être pas aussi aléatoire que je le pensais.chiffres. En effet, j’ai enveloppé la fonction dans une boucle afin de générer des milliers de nombres et, bien sûr, pour de très grands nombres, la variation n’était que de 2 ordres de grandeur.}

Pourquoi?

Voici la version en boucle, vous pouvez donc l'essayer vous-même:

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

Cela inclut à la fois une implémentation simple tirée de Mozilla Developer Network et du code de 1997 que j'ai extrait d'une page Web qui n'existe plus ("Central Randomizer 1.3" de Paul Houle). Voir le source pour voir comment chaque méthode fonctionne.

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

108
Andrew Hedges

Nombre donné entre 1 et 100. 

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

Nombre donné entre 1 et 1000.

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

etc.

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

165
Quentin

Vos résultats sont réellement attendus. Si les nombres aléatoires sont uniformément répartis dans une plage allant de 1 à 10 ^ n, alors vous vous attendez à ce que 9/10 des nombres aient n chiffres et 9/100 supplémentaires n.

54
jwoolard

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 suggérerais d'utiliser une fonction exponentielle pour créer ce qu'on appelle une distribution de 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 les nombres à 2 chiffres et les nombres à 3 chiffres.

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

41
Christian

L'article suivant explique comment math.random () dans les principaux navigateurs Web est (non) sécurisé: "Suivi utilisateur temporaire dans les principaux navigateurs et informations interdomaines Fuites et attaques" par Amid Klein (2008) Ce n'est pas plus fort que les fonctions PRNG intégrées de Java ou de Windows.

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

18
jj1bdx

Cela me semble parfaitement aléatoire! (Indice: cela dépend du navigateur.)

Personnellement, je pense que ma mise en œuvre serait meilleure, même si je l'ai volée à XKCD , qui devrait TOUJOURS être reconnu:

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

Si vous utilisez un nombre comme 10000000000000000000, vous allez au-delà de la précision du type de données utilisé par Javascript. Notez que tous les nombres générés se terminent par "00".

5
Greg

J'ai essayé le générateur de nombres pseudo-aléatoires JS sur Chaos Game .

Mon triangle Sierpiński triangle dit son joli hasard: Fractal

5
zie1ony

Eh bien, si vous générez des nombres allant jusqu'à, par exemple, 1e6, vous obtiendrez tous les nombres avec une probabilité approximativement égale. Cela signifie également que vous n'avez qu'une chance sur dix d'obtenir un nombre avec un chiffre en moins. Une chance sur cent d’obtenir deux chiffres de moins, etc. Je doute que l’utilisation d’un autre GNA changera beaucoup, car votre distribution est uniforme, pas leur logarithme.

3
Joey

Les nombres non aléatoires uniformément répartis de 1 à N ont la même propriété. Notez que (dans un certain sens) c'est une question de précision. Une distribution uniforme sur 0-99 (sous forme d'entiers) a 90% de ses nombres ayant deux chiffres. Une distribution uniforme sur 0-999999 a 905 de ses numéros ayant cinq chiffres. 

Tout ensemble de nombres (dans certaines conditions pas trop restrictives) a une densité. Lorsque quelqu'un veut discuter de nombres "aléatoires", il convient de spécifier la densité de ces nombres (comme indiqué ci-dessus). Une densité commune est la densité uniforme. Il y en a d'autres: la densité exponentielle, la densité normale, etc. Il faut choisir quelle densité est pertinente avant de proposer un générateur de nombres aléatoires. De plus, les nombres provenant d'une densité peuvent souvent être facilement transformés en une autre densité par des moyens financiers.

0
ttw