Verwerfen Casting und Assignment wirklich jede Extra-Präzision von Floats?

9

Ich lese die neue C ++ FAQ und sehe das auch, wenn x == y Für double x, y; ist das möglich für:

%Vor%

wird in false ausgewertet. Dies liegt daran, dass die Maschine einen Prozessor haben kann, der erweiterte Genauigkeit unterstützt, so dass ein Teil des == eine 64-Bit-Nummer ist, während der andere eine 80-Bit-Nummer ist.

Das nächste Beispiel scheint jedoch falsch zu sein:

%Vor%

Soweit ich hier auf en.cppreference.com nachlesen :

  

Cast und Assignment entfernen jegliche irrelevante Entfernung und Präzision:   Dies modelliert die Aktion des Speicherns eines Werts aus einer erweiterten Genauigkeit   FPU-Register in einen Speicherbereich mit Standardgröße.

Somit wird Folgendes zugewiesen:

%Vor%

sollte jede Extrapräzision wegschneiden und das Programm perfekt vorhersagbar machen.

Also, wer hat Recht? Die C ++ - FAQ oder die en.cppreference.com?

    
Martin Drozdik 05.05.2016, 20:23
quelle

2 Antworten

3

Weder die ISOCPP-FAQ noch die cppreference sind autorisierende Quellen. cppreference ist im Wesentlichen das Äquivalent von wikipedia: es enthält gute Informationen, aber jeder kann etwas hinzufügen, ohne Quellen müssen Sie es mit einem Körnchen Salz lesen. Sind die folgenden drei Aussagen wahr:

  

Hast du das verstanden? Ihre spezielle Installation speichert möglicherweise das Ergebnis eines cos () -Aufrufs in den RAM-Speicher, schneidet ihn dabei ab und vergleicht später den abgeschnittenen Wert mit dem nicht abgeschnittenen Ergebnis des zweiten cos () -Aufrufs. Abhängig von vielen Details sind diese beiden Werte möglicherweise nicht gleich.

     

Dies liegt daran, dass die Maschine einen Prozessor haben kann, der erweiterte Genauigkeit unterstützt, so dass ein Teil von == eine 64-Bit-Nummer ist, während der andere eine 80-Bit-Nummer ist.

     

Cast und Assignment streichen jeden irrelevanten Bereich und jegliche Präzision weg: Dies modelliert die Aktion des Speicherns eines Werts aus einem FPU-Register mit erweiterter Genauigkeit in einen Speicherbereich mit Standardgröße.

Vielleicht. Es hängt von der Plattform, Ihrem Compiler, den Compileroptionen oder einer beliebigen Anzahl von Dingen ab. Realistisch gesehen gelten die obigen Aussagen nur für GCC im 32-Bit-Modus, der standardmäßig auf die Legacy-FPU x87 (wobei intern alles 80 Bit ist) und beim Speichern im Speicher auf 64 Bit abgerundet wird. 64-Bit verwendet SSE, so dass doppelte Provisorien immer 64-Bit sind. Sie können SSE mit mfpmath=sse und -msse2 erzwingen. In jedem Fall sieht die Assembly so aus:

%Vor%

Wie Sie sehen können, gibt es weder eine Abschneidung irgendeiner Art noch 80-Bit-Register, die hier verwendet werden.

    
quelle
1

Ich wünschte, diese Aufgabe oder mein Casting würde die extra Präzision wegwerfen. Ich habe mit "cleveren" Compilern gearbeitet, für die das nicht passiert. Viele tun, aber wenn Sie wirklich maschinenunabhängigen Code möchten, müssen Sie zusätzliche Arbeit leisten.

Sie können den Compiler zwingen, immer den Wert im Speicher mit der erwarteten Genauigkeit zu verwenden, indem Sie die Variable mit dem Schlüsselwort "volatile" deklarieren.

Einige Compiler übergeben Parameter in Registern und nicht auf dem Stapel. Bei diesen Compilern könnte es sein, dass x oder y unbeabsichtigte zusätzliche Genauigkeit haben könnten. Um völlig sicher zu sein, könntest du

machen %Vor%     
Reality Pixels 08.05.2016 04:47
quelle

Tags und Links