En JavaScript, el valor de NaN se puede representar mediante una amplia gama de dobles de 64 bits internamente. Específicamente, cualquier doble con la siguiente representación bit a bit:
x111 1111 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
Se interpreta como un NaN. Mi pregunta es: supongamos que lanzo dos uniones de 32 bits a un Número JS usando ArrayBuffers, lo paso y luego lo vuelvo a emitir a dos uniones de 32 bits. ¿Los bits recuperados serán los mismos que los originales, o los motores JS pueden cambiar los bits de un NaN a voluntad? En otras palabras, ¿se pueden usar los números JS para almacenar 64 bits sin pérdida?
javascript
ieee-754
MaiaVictor
fuente
fuente
Respuestas:
ECMA-262 9 ª edición, junio de 2018, (la norma a la que se destina JavaScript para ajustarse) dice, en 6.1.6 “el tipo de número”:
24.1.17 "NumberToRawBytes (tipo, valor, isLittleEndian)" dice:
No veo ningún otro pasaje que mencione NaN que sea esclarecedor sobre esta pregunta. Por un lado, 24.1.17 efectivamente nos dice que los bits de un NaN se deben preservar al convertir el NaN en bytes sin formato. Sin embargo, nada más parece decirnos que los bits deben preservarse en otras operaciones. Se podría deducir que esta es la intención, porque este requisito en 24.1.17 no serviría de nada si los bits pudieran ser cambiados arbitrariamente por cualquier otra operación. Pero no confiaría en las implementaciones de JavaScript para implementar esto de conformidad con esa intención.
fuente
Una vez hice una pregunta para Java, sobre la dependencia del hardware de los valores de NaN, y me di cuenta de que algunas CPU convertirían silenciosamente un "NaN de señalización" en un "NaN silencioso" (configurando el bit NaN silencioso) cuando se carga un valor NaN en un registro de procesador. Entonces, al menos uno de los bits, el bit NaN silencioso, no se puede usar para almacenar datos arbitrarios.
El uso de los otros bits, siempre y cuando se establezca el bit NaN silencioso, probablemente sea seguro. Pero todavía parece haber espacio para la dependencia de implementación aquí, y por lo tanto no hay garantía.
Este tipo de problema es la razón por la cual las operaciones de lenguaje normales evitan hacer algo que dependa del valor interno de un NaN, y prefieren tratar todos los NaN como "solo NaN".
fuente
El estándar original IEEE-754 dejó deliberadamente los bits de un NaN hasta la implementación. Proporcionó pistas, como
Puede poner la dirección de memoria original de donde se creó el NaN.
Mientras tanto, la aritmética tiene reglas específicas sobre qué hacer con un NaN, y eso no tiene nada que ver con los bits en la parte inferior. No creo que incluso diga qué hacer al agregar dos NaN: mantener los bits de uno de ellos en lugar de crear otro conjunto de bits. Solo que el resultado debe ser un NaN.
fuente