2014-12-02 6 views
6

nel tentativo di assegnare un NaN a una variabile su un processore x64C++ NaN rappresentazione byte variazioni intervenute assegnazione

*dest = *(float*)&sourceNaN; 

dove

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

Le istruzioni di virgola mobile FLD e FSTP (visibili nel disassemblaggio) cambia il byte 0xa0 in un 0xe0. Quindi la destinazione ha un bit in più impostato. Qualcuno può spiegare perché questo sta accadendo? Questa è un'applicazione Windows.

Il codice di linguaggio assembly:

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

Qualsiasi motivo non è possibile assegnare direttamente dalla [costante NaN] (http://stackoverflow.com/questions/16691207/c-c-nan-constant-literal) direttamente? – tadman

+1

Sono così confuso qui. Prendi l'indirizzo, esegui il cast in un 'float *', e poi dereferenzia? Perché? – Daniel

+3

Perché non farlo in modo diverso non è la domanda. Perché il virgola mobile risultante imposta il bit aggiuntivo è. – Bruce

risposta

7

0x7fa00000 è una segnalazione NaN ("Snan"). 0x7fe00000 è un NaN silenzioso ("qNaN"). Non ho sentito parlare di questo comportamento sotto x86, ma sotto ARM sNaNs viene convertito in qNaNs quando usato nelle operazioni, insieme a generare un'eccezione FP (che normalmente viene ignorata). Sembra che la stessa cosa stia succedendo qui.

La buona notizia è che sono entrambi dei NaN. A meno che non ti affidi specificamente al comportamento di segnalazione, tutto sta andando bene.

+4

x86 converte anche un NaN di segnalazione nell'equivalente NaN piuttosto quando incontra un SNaN mentre l'eccezione non valida viene mascherata. Altrimenti solleva quell'eccezione quando incontra un SNaN. Un SNaN viene "silenziato" impostando il bit frazionario più significativo della mantissa, che è il bit 22 in un numero a precisione singola IEEE-754. – njuffa