Sind die Bitmuster von NaNs wirklich hardwareabhängig?

Ich habe über Fließkomma-NaN-Werte in der Java-Sprachspezifikation gelesen (ich bin langweilig). Ein 32-Bitfloat hat dieses Bitformat:

seee eeee emmm mmmm mmmm mmmm mmmm mmmm

s ist das Vorzeichenbit,e sind die Exponentenbits undm sind die Mantissenbits. Ein NaN-Wert wird als Exponent aller Einsen codiert, und die Mantissenbits sind nicht alle 0 (dies wäre +/- unendlich). Dies bedeutet, dass es viele verschiedene mögliche NaN - Werte gibt (mit unterschiedlichen Werten)s undm Bitwerte).

Auf diesem,JLS §4.2.3 sagt:

IEEE 754 ermöglicht mehrere unterschiedliche NaN-Werte für jedes seiner Einzel- und Doppel-Gleitkommaformate. Während jede Hardwarearchitektur ein bestimmtes Bitmuster für NaN zurückgibt, wenn ein neues NaN generiert wird, kann ein Programmierer auch NaNs mit unterschiedlichen Bitmustern erstellen, um beispielsweise nachträgliche Diagnoseinformationen zu codieren.

Der Text in der JLS scheint zu implizieren, dass das Ergebnis von beispielsweise0.0/0.0, hat ein hardwareabhängiges Bitmuster. Abhängig davon, ob dieser Ausdruck als Kompilierungszeitkonstante berechnet wurde, ist die Hardware, von der er abhängt, möglicherweise die Hardware, auf der das Java-Programm kompiliert wurde, oder die Hardware, auf der das Programm ausgeführt wurde. Das scheint allessehr flockig wenn wahr.

Ich habe folgenden Test durchgeführt:

System.out.println(Integer.toHexString(Float.floatToRawIntBits(0.0f/0.0f)));
System.out.println(Integer.toHexString(Float.floatToRawIntBits(Float.NaN)));
System.out.println(Long.toHexString(Double.doubleToRawLongBits(0.0d/0.0d)));
System.out.println(Long.toHexString(Double.doubleToRawLongBits(Double.NaN)));

Die Ausgabe auf meinem Computer ist:

7fc00000
7fc00000
7ff8000000000000
7ff8000000000000

Die Ausgabe zeigt nichts Außergewöhnliches. Die Exponentenbits sind alle 1. Das obere Bit der Mantisse ist ebenfalls 1, was für NaNs anscheinend ein "ruhiges NaN" im Gegensatz zu einem "signalisierenden NaN" anzeigt (https://en.wikipedia.org/wiki/NaN#Floating_point). Das Vorzeichenbit und der Rest der Mantissenbits sind 0. Die Ausgabe zeigt auch, dass es keinen Unterschied zwischen den auf meiner Maschine generierten NaNs und den konstanten NaNs der Float- und Double-Klassen gab.

Meine Frage ist,Ist diese Ausgabe in Java garantiert, unabhängig von der CPU des Compilers oder der VM, oder ist das alles wirklich unvorhersehbar? Die JLS ist diesbezüglich mysteriös.

Wenn diese Ausgabe für garantiert ist0.0/0.0Gibt es arithmetische Möglichkeiten zur Erzeugung von NaNs mit anderen (möglicherweise hardwareabhängigen?) Bitmustern? (Ich weißintBitsToFloat/longBitsToDouble kann andere NaNs codieren, aber ich möchte wissen, ob andere Werte aus der normalen Arithmetik auftreten können.)

Ein weiterer Punkt: Ich habe das bemerktFloat.NaN undDouble.NaN geben Sie ihr genaues Bitmuster an, aber in der Quelle (Schweben, Doppelt) Sie werden generiert von0.0/0.0. Wenn das Ergebnis dieser Aufteilung wirklich von der Hardware des Compilers abhängt, scheint es einen Fehler in der Spezifikation oder der Implementierung zu geben.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage