En JavaScript, la valeur NaN peut être représentée par une large gamme de doubles 64 bits en interne. Plus précisément, tout double avec la représentation au niveau du bit suivante:
x111 1111 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
Est interprété comme un NaN. Ma question est la suivante: supposons que je jette deux uints 32 bits vers un numéro JS à l'aide d'ArrayBuffers, je le passe, puis je le restitue en deux uints 32 bits. Les bits récupérés seront-ils les mêmes que ceux d'origine, ou les moteurs JS sont-ils autorisés à modifier les bits d'un NaN à volonté? En d'autres termes, les numéros JS peuvent-ils être utilisés pour stocker avec perte 64 bits?
javascript
ieee-754
MaiaVictor
la source
la source
Réponses:
ECMA-262 9 e édition, juin 2018 (la norme à laquelle JavaScript est censé se conformer) dit, en 6.1.6 «Le type de numéro»:
24.1.17 «NumberToRawBytes (type, valeur, isLittleEndian)» dit:
Je ne vois aucun autre passage mentionnant NaN qui soit éclairant sur cette question. D'une part, 24.1.17 nous dit effectivement que les bits d'un NaN doivent être préservés lors de la conversion du NaN en octets bruts. Cependant, rien d'autre ne semble nous dire que les bits doivent être conservés dans d'autres opérations. On pourrait en déduire que c'est l'intention, car cette exigence du 24.1.17 ne servirait à rien si les bits pouvaient être modifiés arbitrairement par toute autre opération. Mais je ne compterais pas sur les implémentations JavaScript pour avoir implémenté cela conformément à cette intention.
la source
Une fois, j'ai posé une question à Java, sur la dépendance matérielle des valeurs NaN, et il a été remarqué que certains processeurs convertissent silencieusement un "NaN de signalisation" en un "NaN silencieux" (définition du bit NaN silencieux) lorsqu'une valeur NaN est chargée dans un registre de processeur. Donc, au moins un des bits, le bit NaN silencieux, vous ne pouvez pas utiliser pour stocker des données arbitraires.
L'utilisation des autres bits, tant que le bit NaN silencieux est défini, est probablement sûre. Mais il semble toujours y avoir de la place pour la mise en œuvre dépendante, et donc aucune garantie.
Ce type de problème explique pourquoi les opérations de langage normales évitent de faire quoi que ce soit qui dépend de la valeur interne d'un NaN, et préfèrent traiter tous les NaN comme "juste NaN".
la source
La norme IEEE-754 d'origine a délibérément laissé les bits d'un NaN à la mise en œuvre. Il a fourni des conseils, tels que
Vous pouvez mettre l'adresse mémoire d'origine de l'endroit où le NaN a été créé.
Pendant ce temps, l'arithmétique a des règles spécifiques sur ce qu'il faut faire avec un NaN, et cela n'a rien à voir avec les bits en bas. Je ne pense pas qu'il indique même quoi faire lors de l'ajout de deux NaN - conserver les bits de l'un d'eux par rapport à constituer un autre ensemble de bits. Juste que le résultat doit toujours être un NaN.
la source