C / C ++ NaN stała (dosłownie)?

110

Czy jest możliwe przypisanie a NaNdo a doublelub floatw C / C ++? Podobnie jak w JavaScript zrobić: a = NaN. Więc później możesz sprawdzić, czy zmienna jest liczbą, czy nie.

exebook
źródło
Tutaj pokazuję, jak różne NaN wyglądają, gdy są generowane różnymi sposobami: stackoverflow.com/questions/18118408/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

153

W C NANjest zadeklarowana w<math.h> .

W C ++ std::numeric_limits<double>::quiet_NaN()jest zadeklarowana w <limits>.

Ale aby sprawdzić, czy wartość to NaN, nie możesz porównać jej z inną wartością NaN. Zamiast tego używaj isnan()from <math.h>w C lub std::isnan()from <cmath>w C ++.

Mike Seymour
źródło
20
Lub możesz porównać liczbę ze sobą - x == xzwraca falseiff xto NaN.
Archie
7
@Archie: Nie sądzę, że jest to gwarantowane w żadnym języku.
Mike Seymour
3
@MikeSeymour Nie według standardu języka, ale o ile wiem, powinno działać, jeśli kompilator twierdzi, że jest zgodny z IEEE.
Pixelchemist
37
@Pixelchemist: Rzeczywiście, jest to opcja, jeśli potrzebujesz zaciemnienia, ale nie przenośności. Osobiście wolę przenośność bez zaciemniania, więc nie będę tego sugerował.
Mike Seymour
9
drobna uwaga: NAN to liczba zmiennoprzecinkowa, a nie podwójna. link
orion elenzil
23

Jak zauważyli inni, szukasz, std::numeric_limits<double>::quiet_NaN()chociaż muszę powiedzieć, że wolę dokumenty cppreference.com . Zwłaszcza, że ​​to stwierdzenie jest trochę niejasne:

Ma znaczenie tylko wtedy, gdy std :: numeric_limits :: has_quiet_NaN == true.

i łatwo było dowiedzieć się, co to oznacza na tej stronie, jeśli sprawdzisz ich sekcję na std::numeric_limits::has_quiet_NaNjej temat:

Ta stała ma znaczenie dla wszystkich typów zmiennoprzecinkowych i gwarantuje, że będzie prawdziwa, jeśli std :: numeric_limits :: is_iec559 == true.

co, jak wyjaśniono tutaj , trueoznacza, że ​​Twoja platforma obsługuje IEEE 754standard. Ten poprzedni wątek wyjaśnia, że ​​powinno to być prawdą w większości sytuacji.

Shafik Yaghmour
źródło
9

Można to zrobić za pomocą numeric_limits w C ++:

http://www.cplusplus.com/reference/limits/numeric_limits/

Oto metody, którym prawdopodobnie chcesz się przyjrzeć:

infinity()  T   Representation of positive infinity, if available.
quiet_NaN() T   Representation of quiet (non-signaling) "Not-a-Number", if available.
signaling_NaN() T   Representation of signaling "Not-a-Number", if available.
językoznawstwo
źródło
6
+1. Wikipedia zawiera informacje o cichym NaN i sygnalizującym NaN .
Drew Noakes
1

Czy jest możliwe przypisanie NaN do double lub float w C ...?

Tak, ponieważ C99, (C ++ 11) <math.h>oferuje następujące funkcje:

#include <math.h>
double nan(const char *tagp);
float nanf(const char *tagp);
long double nanl(const char *tagp);

które są jak ich strtod("NAN(n-char-sequence)",0)odpowiedniki i NANdo zadań.

// Sample C code
uint64_t u64;
double x;
x = nan("0x12345");
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);
x = -strtod("NAN(6789A)",0);
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);
x = NAN;
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);

Przykładowe dane wyjściowe: (zależne od implementacji)

(7ff8000000012345)
(fff000000006789a)
(7ff8000000000000)
chux - Przywróć Monikę
źródło
1
Jakie są różnice między wyjściami dla różnych ciągów? Którego należy użyć w typowym kodzie numerycznym?
quant_dev