2014-12-02 2 views
6

Bei dem Versuch, ein NaN auf eine Variable auf einem x64-Prozessor in der DemontageC++ NaN Bytedarstellung Änderungen bei der Zuordnung

*dest = *(float*)&sourceNaN; 

wo

unsigned char sourceNaN[] = {00,00, 0xa0, 0x7f}; 

Die Gleitkommabefehle fld und FSTP (gesehen zuzuweisen) Ändern Sie das 0xa0-Byte in ein 0xe0. Somit hat das Ziel ein zusätzliches Bit gesetzt. Kann jemand erklären, warum das passiert? Dies ist eine Windows-Anwendung.

der Assemblersprachcode:

005C9B9C mov   eax,dword ptr [ebp+10h] 
005C9B9F fld   dword ptr [ebp-80h] 
005C9BA2 fstp  dword ptr [eax] 
+5

Jeder Grund, den Sie nicht direkt von der [NaN-Konstante] (http://stackoverflow.com/questions/16691207/c-c-nan-constant-literal) zuweisen können? – tadman

+1

Ich bin hier so verwirrt. Du nimmst die Adresse, wirfst zu einem 'float *' und dann dereferenziertest du? Warum? – Daniel

+3

Warum nicht anders ist nicht die Frage. Warum das resultierende Gleitkomma das zusätzliche Bit setzt, ist. – Bruce

Antwort

7

0x7fa00000 ist ein Signalisierungs NaN ("SNaN"). 0x7fe00000 ist ein ruhiges NaN ("qNaN"). Ich habe von diesem Verhalten unter x86 nichts gehört, aber unter ARM sNaNs werden bei der Verwendung in Operationen zu qNaNs konvertiert, neben dem Anheben einer FP-Ausnahme (die normalerweise ignoriert wird). Es sieht so aus, als würde hier dasselbe passieren.

Die gute Nachricht ist, sie sind beide NaNs. Wenn Sie sich nicht speziell auf das Signalverhalten verlassen, läuft alles gut.

+4

x86 konvertiert auch ein Signalisierungs-NaN in das äquivalente NaN, wenn es auf ein SNaN trifft, während die ungültige Ausnahme maskiert ist. Andernfalls wird diese Ausnahme ausgelöst, wenn ein SNaN auftritt. Ein SNaN wird "beruhigt", indem das höchstwertige Bruchteil der Mantisse gesetzt wird, das Bit 22 in einer IEEE-754-Zahl mit einfacher Genauigkeit. – njuffa