JSエンジンはNaNのビットを変更できますか?


12

JavaScriptでは、NaN値は、内部的には広範囲の64ビットdoubleで表すことができます。具体的には、次のビットごとの表現を持つ任意のdouble:

x111 1111 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

NaNとして解釈されます。私の質問は、ArrayBuffersを使用して2つの32ビットuintをJS番号にキャストし、渡してから、2つの32ビットuintにキャストするとします。復元されたビットは元のビットと同じですか、それともJSエンジンはNaNのビットを自由に変更できますか?言い換えれば、JS番号を使用して64ビットを無損失で格納できますか?


2
興味深いアイデア
エバート、

1
私が作ったテスト。少なくともNode.jsは思いのままにビットを変更し、情報が失われるようです。
MaiaVictor

1
余談:そのようなビットパターンのすべてがNaNを表すわけではありません。最初のxの後のすべてのxがゼロの場合、それは無限大を表します。
Eric Postpischil

回答:


6

ECMA-262 9 版、2018年6月(JavaScriptが準拠することを意図した標準)は、6.1.6の「数値タイプ」で次のように述べています。

… IEEE標準の9007199254740990(つまり、2 53 -2)の個別の「Not-a-Number」値は、ECMAScriptで単一の特別なNaN値として表されます。…一部の実装では、外部コードが違いを検出できる場合がありますさまざまなNot-a-Number値の間。ただし、そのような動作は実装に依存します。ECMAScriptコードでは、すべてのNaN値は互いに区別できません。

24.1.17“ NumberToRawBytes(type、value、isLittleEndian)”は言う:

…値がNaNの場合、rawBytesは、IEEE 754-2008のbinary64形式のNot-a-Numberエンコーディングで選択された実装に設定できます。実装では、実装ごとに区別可能なNaN値に常に同じエンコーディングを選択する必要があります。…

この質問に光を当てているNaNについて言及している他の箇所はありません。一方、24.1.17は、NaNをrawバイトに変換するときに、NaNのビットを保持する必要があることを効率的に通知します。ただし、他の操作でビットを保持する必要があることを示すものは他にありません。24.1.17のこの要件は、ビットが他の操作によって任意に変更される可能性がある場合、目的を果たさないため、これが意図であると推測する場合があります。しかし、JavaScriptの実装に依存して、その意図に従ってこれを実装したことはありません。


1

私は一度尋ねた質問を NaN値のハードウェア依存性については、Javaのため、そしてそれはいくつかのCPUは黙って「ワイアットNaN」(クワイエットNaNのビットを設定)NaN値がロードされたときに、「シグナルはNaNを」変換することに気づきました。プロセッサレジスタに。したがって、ビットの少なくとも1つであるクワイエットNaNビットは、任意のデータの格納には使用できません。

他のビットの使用は、クワイエットNaNビットが設定されている限り、おそらく安全です。しかし、それでもここには実装依存の余地があるようで、保証はありません。

この種の問題は、通常の言語操作がNaNの内部値に依存することを一切行わず、すべてのNaNを「単なるNaN」として扱うことを好む理由です。


0

元のIEEE-754標準では、意図的にNaNのビットを実装に任せていました。次のようなヒントを提供しました

NaNが作成された元のメモリアドレスを入力する場合があります。

一方、算術にはNaNをどうするかに関する特定のルールがあり、それは下部のビットとは何の関係もありません。2つのNaNを追加するときに何をすべきかについても述べていないと思います-そのうちの1つからのビットを保持するのではなく、別のビットのセットを構成します。結果はまだNaNでなければなりません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.