В JavaScript значение NaN может быть внутренне представлено широким диапазоном 64-битных двойных чисел. В частности, любой дубль со следующим побитовым представлением:
x111 1111 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
Это интерпретируется как NaN. Мой вопрос: предположим, что я приведу две 32-битные уинты к JS-номеру с помощью ArrayBuffers, передам его, а затем приведу обратно к двум 32-битным уинтам. Будут ли восстановленные биты такими же, как исходные, или JS-движкам разрешено изменять биты NaN по желанию? Другими словами, могут ли номера JS использоваться для хранения 64-битных данных без потерь?
javascript
ieee-754
MaiaVictor
источник
источник
Ответы:
ECMA-262, 9- е издание, июнь 2018 г. (стандарт, которому должен соответствовать JavaScript) в 6.1.6 «Тип числа» гласит:
24.1.17 «NumberToRawBytes (тип, значение, isLittleEndian)» говорит:
Я не вижу других отрывков, в которых упоминается NaN, освещающих этот вопрос. С одной стороны, 24.1.17 фактически говорит нам, что биты NaN должны быть сохранены при преобразовании NaN в необработанные байты. Однако больше ничего не говорит нам, что биты должны быть сохранены в других операциях. Можно сделать вывод, что это намерение, потому что это требование в 24.1.17 не будет иметь смысла, если биты могут быть произвольно изменены любой другой операцией. Но я бы не стал полагаться на реализации JavaScript, чтобы реализовать это в соответствии с этим намерением.
источник
Однажды я задал вопрос для Java об аппаратной зависимости значений NaN, и было замечено, что некоторые процессоры будут молча преобразовывать «сигнальный NaN» в «тихий NaN» (устанавливая тихий бит NaN) при загрузке значения NaN в регистр процессора. Поэтому, по крайней мере, один из битов, тихий бит NaN, вы не можете использовать для хранения произвольных данных.
Использование других битов, пока установлен тихий бит NaN, вероятно, безопасно. Но все же, похоже, здесь есть место для зависимости от реализации, и, следовательно, нет никакой гарантии.
Проблема такого рода заключается в том, что обычные языковые операции избегают делать что-либо, зависящее от внутреннего значения NaN, и предпочитают рассматривать все NaN как «просто NaN».
источник
Первоначальный стандарт IEEE-754 намеренно оставил биты NaN вплоть до реализации. Он предоставил подсказки, такие как
Вы можете поместить оригинальный адрес памяти, где был создан NaN.
Между тем, арифметика имеет определенные правила о том, что делать с NaN, и это не имеет ничего общего с битами внизу. Я не думаю, что это даже говорит о том, что делать при добавлении двух NaN - сохранить биты одного из них вместо создания другого набора битов. Просто результат должен быть NaN.
источник