2014-12-02 12 views
6

próbując przypisać NaN do zmiennej na procesorze x64C++ NaN zmiany reprezentacją podczas przypisywania

*dest = *(float*)&sourceNaN; 

gdzie

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

W instrukcji zmiennoprzecinkowych FLD i FSTP (obserwowane w demontażu) zmień bajt 0xa0 na 0xe0. Zatem miejsce docelowe ma dodatkowy zestaw bitów. Czy ktoś może wyjaśnić, dlaczego tak się dzieje? To jest aplikacja dla systemu Windows.

Zespół kod języka:

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

Każdy powód, którego nie można po prostu przypisać bezpośrednio ze stałej [NaN] (http://stackoverflow.com/questions/16691207/c-c-nan-constant-literal)? – tadman

+1

Jestem taki zdezorientowany. Przyjmujesz adres, rzucasz na "float *", a potem dereference? Czemu? – Daniel

+3

Dlaczego nie robić tego inaczej, nie jest to pytanie. Dlaczego wynikowy zmiennoprzecinkowy ustawia dodatkowy bit. – Bruce

Odpowiedz

7

0x7fa00000 jest sygnalizacja NaN ("sNaN"). 0x7fe00000 jest cichym NaN ("qNaN"). Nie słyszałem o tym zachowaniu pod x86, ale w ramach ARM sNaNs są konwertowane na qNaNs, gdy są używane w operacjach, wraz z podnoszeniem wyjątku FP (który jest zwykle ignorowany). Wygląda na to, że to samo dzieje się tutaj.

Dobrą wiadomością jest to, że obie są NaN. Jeśli nie polegasz na działaniu sygnalizacyjnym, wszystko idzie dobrze.

+4

x86 także konwertuje sygnalizacyjny NaN na równoważny całkiem NaN po napotkaniu SNaN, podczas gdy nieprawidłowy wyjątek jest zamaskowany. W przeciwnym razie podnosi ten wyjątek podczas napotykania SNaN. SNaN jest "wyciszony" poprzez ustawienie najbardziej znaczącego bitu cząstkowego mantysy, który jest bitem 22 w liczbie pojedynczej precyzji IEEE-754. – njuffa

Powiązane problemy