10
votes

Quelle est la valeur minimale non nulle math.random () peut revenir en JavaScript

Je sais que les ordinateurs ne peuvent pas travailler avec des continuums. Math.Random () La fonction JavaScript renvoie un numéro de point flottant entre 0 (inclusivement) et 1 (exclusivement). Je me demande quel est le nombre minimal non zéro qu'il peut revenir. Quelle "étape" a cette fonction?


3 commentaires

Je crois que dans la plupart des implémentations, la granularité est 2 ^ 53. La réponse serait donc 2 ^ -53.


La spécification dit à l'aide d'un algorithme ou d'une stratégie dépendant de la mise en œuvre , Je suppose que le résultat le plus petit est ce que 1 / numéro.max_value vous donne (supposant non-zéro résultat, par exemple 5.562684646268003e-309 )


La valeur ponctuelle flottante le rend intéressant. Pour une implémentation C typique C, qui renvoie un integer , rand_max peut être aussi bas que 65535. Bien sûr, cela peut conduire à de nombreuses petites décimales, finalement la granularité est de 1 / 65536, qui est à peu près à environ 4 décimales et bits.


4 Réponses :


6
votes

La norme n'exprime sûrement pas cette valeur. Cela dépend donc de la mise en œuvre (et d'exagérer un peu sur ce point, probablement même une implémentation que les éloignages de 0,42 résultent pour math.random () est toujours conforme à la spécification).

Le plus petit nombre positif pouvant être représenté par un numéro de point flottant normalisé 64 bits dans le format IEEE754 est 2 -1022 , à savoir 2.2250738585072014 × 10 -308 . < / p>

Cependant, la représentation de points flottants utilise une résolution variable, en fonction de la magnitude.

Pour les chiffres proches de 1 La résolution est 2 -53 . Probablement (juste probablement ) de nombreuses implémentations choisissent un numéro d'entier aléatoire N compris entre 0 et 2 53 -1 et utiliser comme résultat n / n / n / 9007199254740992 .


2 commentaires

Qui ressemble numéro comme celui-ci en décimal: 0,0000000000000000000000000000000000000000000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000022250738585 072014. C'est assez petit.


Ce que je trouve étonnant, c'est que si vous passez cette chaîne décimale à une chaîne de conversion de flotteur, le résultat est correct (même si bien sûr, c'est l'un des cas de test qu'ils utilisent).



1
votes

Il n'est presque certainement pas de choisir un flotté aléatoire.

Cela ne représenterait pas exactement l'étape de la fonction aléatoire, car il ne serait même pas proche de la distribution uniforme. Disons que vous avez obtenu cette 2 -1022 "pas" (la plus petite valeur non nulle qui convient à un flotteur), plus 0,25 comme valeur aléatoire. Eh bien, cela serait arrondi à 0,25 parce que des flotteurs ne peuvent pas représenter cette précision. Donc, vous avez une bande complète de «valeurs» qui sont toutes égales à 0,25 en raison de l'arrondi. Ce n'est même pas uniforme à distance.

Je dirais qu'il est plus probable qu'un float soit généré avec l'exposant réglé sur 0 avec des bits aléatoires pour la mantissa, ce qui entraînerait une aléatoire de l'étape 2 -51 (je pense XD) entre 1 (inclus) et 2 (non inclus), à partir duquel vous pouvez alors simplement soustraire 1. Dans ce cas, l'étape serait la taille de la mantissie.


5 commentaires

Sur quelle partie vous n'êtes pas d'accord? Celui dans lequel je dis que la norme ne couvre pas ce point ou la pièce dans laquelle je déclare quel est le plus petit nombre qui peut être représenté par un numéro de double précision?


@ 6502 Les deux parties sont correctes, mais la seconde n'est pas vraiment pertinente et trompeuse dans ce contexte, car il suggère un peu que vous prétendez que l'étape de la fonction aléatoire. Au moins, c'est comme ça que je l'ai interprété xD


Point prononcé quand même. Édité la réponse à ce qui est (probablement) quelle implémentation peut faire pour extraire des nombres aléatoires uniformes.


"Cueillir des bits aléatoires" ... sûrement le format de stockage de points flottant ferait partiellement biais le résultat? (Doit trouver référence. Je SAVOIR Cela mènera à une écart logarithmique plutôt que linéaire.)


@Jongware: Vous pouvez faire une propagation uniforme en fixant l'exposant et choisir au hasard les 52 bits de Mantissa. Plus tard, vous pouvez normaliser la représentation.



-1
votes

Je ne sais pas ce que la spécification dit, mais un test rapide dans la console de Chrome, Firefox et IE11 montre que la précision ne va jamais au-delà de 20 décimales.

Testez-le vous-même: < Pré> xxx

ou pour voir le plus petit nombre après un grand nombre d'itérations: xxx


7 commentaires

Je ne suis pas très familier avec JavaScript, mais quelles sont les chances que console.log n'écrit que 20 décimales par défaut?


Ce type de test est un vraiment mauvais moyen de déterminer les valeurs minimales. Il existe une quantité inimallablement importante de nombres compris entre 1,0 et 10 ^ (- 20) de sorte que les chances que aléatoire () choisit un nombre inférieur à 10 ^ (- 20) est pratiquement zéro - peu importe le nombre de itérations que vous choisissez pour votre boucle. Donc, même si cela est possible, vous ne verriez jamais aléatoire () générer un nombre inférieur à 10 ^ (- 20) simplement parce qu'il est si incroyablement improbable.


D'une perspective purement mathématique, vous auriez besoin d'au moins 10 ^ 20 itérations pour avoir même une photo pour obtenir une valeur inférieure à 10 ^ (- 20). Et si nous oublions un instant à quel point cela est inefficace de faire quelque chose comme ça est que vous ne pouvez toujours pas être sûr que votre réponse est correcte. Parce que peu importe le nombre d'itérations que vous exécutez, il y a toujours la possibilité que vous ayez simplement été malchanceux et que le nombre le plus bas possible n'a toujours pas été retourné. Donc, pour revenir à ma déclaration originale, vraiment un mauvais moyen de déterminer quelque chose comme ça.


@MOOINGDUCK: La console génère une précision complète à l'aide de la notation E, de sorte que ce n'est pas un facteur limitant.


@Xaverkapeller: Je ne vous suggère pas que vous puissiez obtenir le plus petit nombre avec mon approche. J'ai dit que vous pourriez avoir le plus petit nombre "après un grand nombre d'itérations". Mon point était que chaque nombre dans un ensemble de 1 000 000 est tombé à quelques chiffres de 20 décimales de précision, de sorte que la gamme que vous puissiez attendre des appels à Math.Random ().


Eh bien, je l'ai eu, mon point est que ce soit une information inutile. Imaginez 100 000 personnes utilisent votre site Web pendant un an. Même s'il n'y a qu'un seul appel à aléatoire () par page Visitez alors vous allez avoir beaucoup d'appels plus d'appels que 1 000 000 en cette année. Vous ne pouvez pas faire des hypothèses comme celle-ci dans un environnement de production.


@Xaverkapeller 64 bits La granularité entraînerait un minimum de 5,421010109e-20, qui est assez proche de la mesure de Bradon. Je parie que ce n'est pas une coïncidence.



0
votes

1 commentaires

Je crois fermement que supposer que chaque utilisateur utilise une implémentation est paresseux et généralement mauvais conseil. Que vous l'aimiez ou non, d'autres navigateurs sont utilisés utilisés et doivent être comptabilisés.