2011-01-20 35 views
10

Powiel możliwe:
Checking if a double (or float) is nan in C++Sprawdzanie czy wartość float jest NaN

Mam wymaganie, aby sprawdzić czy pływak jest NaN. Przeglądając niektóre linki, znalazłem najczęściej sprawdzany.

FLOAT32 f32_test_NaN = (some_value); 
if (f32_test_NaN == f32_test_NaN) 
{ 
    //do something; 
} 
else 
{ 
    // do something; 
} 

Ale to nie wydaje się działać dla mnie. Mój kod wygląda następująco:

FLOAT32 test_NaN = 0x414570A3;//some value - is this ok? 

debugowanie GDB:

(gdb) p test_NaN 
$1 = 1.09506982e+09 

(gdb) p/x test_NaN 
$2 = 0x41457080 // Hex is not same as init value - What is compiler doing? 

Więc w moim przypadku test_NaN jest równa test_NaN.

Proszę dać mi znać, jeśli jakiekolwiek ustawienie kompilatora musi być wykonane. Używam solaris. Czy istnieje inny sposób sprawdzenia tego samego.

Z góry dziękuję.

+1

http://stackoverflow.com/questions/570669/checking-if-a-double-or-float-is-nan-in -c –

+3

Dlaczego nie używać 'isnan()' z math.h? Jakieś specjalne powody? – Constantin

+0

Ta standardowa funkcja nie jest dostępna w środowisku. – kp11

Odpowiedz

1

Problemem jest to, być może w swojej inicjacji (przynajmniej wyjaśnia wartość widoczny gdb):

FLOAT32 test_NaN = 0x414570A3; 

Podana wartość szesnastkowa jest traktowana jako liczba całkowita i konwertowana do postaci zmiennoprzecinkowej (z wykładnikiem i wartością), co oznacza, że ​​jest przechowywana w innym formacie.

Jeśli chcesz zmusić bitów wewnątrz pływaka, to trzeba memcpy: (! X = x)

FLOAT32 test_NaN; 
memcpy(&test_NaN, 0x414570A3, 4); 
+0

Cool !! Wiedziałem, że problem istnieje. Ale memcpy rozbił się na mnie. Stąd właśnie to zrobiło i zadziałało !! UINT32 test_NaN [2] = {0xffffffff, 0xfffffff7}; Test FLOAT32 = * (FLOAT32 *) test_NaN; (nie pokazuje wskaźników w komentarzach (?!?)) – kp11

+2

Twój kod jest niepoprawny. memcpy musi kopiować z adresu. Więc najpierw przechowuj 0x414570A3 w zmiennej int. – Calmarius

22

Dołącz math.h i użyj int isnan(x). Nie zapomnij, aby połączyć ze -lm

+1

Być może należy dodać, że ten "tylko" pojawił się w C99, więc nie wszystkie kompilatory mogą to jeszcze zaimplementować. –

+1

suncc obsługuje to, co wydaje się być tym, czego używa osoba pytająca. –

+0

W rzeczywistości 'isnan' nie jest funkcją, przynajmniej jeśli użyjesz go po dodaniu' math.h': jest to makro z definicją zdefiniowaną przez implementację. – Ruslan

6

Jeśli <math.h> nie jest dostępny, to zrobić:

if (x != x) 
{ 
    // x is NaN 
} 
+0

Dzięki, to samo robię, ale prawdopodobnie nie zainicjuję poprawnie. Czy możesz mi powiedzieć, jaką wartość mogę zainicjować "x", aby przetestować dla NaN? – kp11

+0

@kartik: 'x = 0.0; x/= x; ' –

6

jeśli

Dla x = 0x7FBFFFFF (bit znaku 0, a = 0, reszta bitów 1)

http://en.wikipedia.org/wiki/NaN

przykładu bitową z IEEE zmiennoprzecinkowym standardowe jednoliterowe precyzji (32-b it) NaN: s111 1111 1axx xxxx xxxx xxxx xxxx xxxx gdzie s jest znakiem, x jest ładunkiem, a określa typ NaN. Jeśli a = 1, jest to cichy NaN; jeśli a jest zerowe, a ładunek jest niezerowy, to jest to sygnalizacja NaN

Powiązane problemy