Разрешено ли двигателям JS изменять биты NaN? - PullRequest
10 голосов
/ 07 ноября 2019

В 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-битных данных без потерь?

Ответы [ 2 ]

5 голосов
/ 08 ноября 2019

ECMA-262 9 th Edition, июнь 2018 г. (стандарт, которому должен соответствовать JavaScript) в 6.1.6 «Тип номера» гласит:

… 9007199254740990 (то есть 2 53 -2) различных значений «не числа» стандарта IEEE представлены в ECMAScript как отдельное специальное значение NaN.… В некоторых реализациях внешний кодможет быть в состоянии обнаружить разницу между различными значениями Not-a-Number, но такое поведение зависит от реализации;к коду ECMAScript все значения NaN неотличимы друг от друга.

24.1.17 «NumberToRawBytes (type, value, isLittleEndian)» говорит:

… Если значение равноNaN, rawBytes может быть установлен на любую реализацию, выбранную IEEE 754-2008 для двоичного формата64 Кодирование не числа. Реализация должна всегда выбирать одну и ту же кодировку для каждого различимого значения реализации NaN.…

Я не вижу других отрывков, в которых упоминается NaN, которые освещают этот вопрос. С одной стороны, 24.1.17 эффективно говорит нам, что биты NaN должны быть сохранены при преобразовании NaN в необработанные байты. Однако больше ничего не говорит нам, что биты должны быть сохранены в других операциях. Можно сделать вывод, что это и есть намерение, потому что это требование в 24.1.17 не будет иметь смысла, если биты могут быть произвольно изменены любой другой операцией. Но я бы не стал полагаться на реализации JavaScript для реализации этого в соответствии с этим намерением.

1 голос
/ 08 ноября 2019

Я однажды задал вопрос для Java о аппаратно-зависимых значениях NaN, и было замечено, что некоторые процессоры будут молча преобразовывать «сигнальный NaN» в «тихий NaN» (настройкаБит NaN), когда значение NaN загружается в регистр процессора. Таким образом, по крайней мере один из битов, тихий бит NaN, вы не можете использовать для хранения произвольных данных.

Использование других битов, пока установлен тихий бит NaN, равно вероятно безопасно. Но, тем не менее, здесь, похоже, есть место для зависимости от реализации, и, следовательно, нет гарантии.

Проблема такого рода заключается в том, что обычные языковые операции избегают делать что-либо, зависящее от внутреннего значения NaN, и предпочитают обрабатыватьвсе NaNs как "просто NaN".

...