Constante C / C ++ NaN (literal)?

110

É possível atribuir NaNa a doubleou floatem C / C ++? Como em JavaScript você faz: a = NaN. Posteriormente, você poderá verificar se a variável é um número ou não.

exebook
fonte
Aqui eu mostro como vários NaNs se parecem quando gerados por meios diferentes: stackoverflow.com/questions/18118408/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respostas:

153

Em C, NANé declarado em <math.h>.

Em C ++, std::numeric_limits<double>::quiet_NaN()é declarado em <limits>.

Mas para verificar se um valor é NaN, você não pode compará-lo com outro valor NaN. Em vez disso usar isnan()a partir <math.h>de C, ou std::isnan()a partir <cmath>de C ++.

Mike Seymour
fonte
20
Ou você pode comparar o número com ele mesmo - x == xretorna falseiff xé NaN.
Archie
7
@Archie: Não acho que isso seja garantido em nenhum dos idiomas.
Mike Seymour
3
@MikeSeymour Não pelo padrão de linguagem, mas pelo que eu sei, deve funcionar se o compilador declarar ser compatível com IEEE.
Pixelchemist de
37
@Pixelchemist: Na verdade, é uma opção se você precisar de ofuscação, mas não de portabilidade. Pessoalmente, prefiro portabilidade sem ofuscação, então não vou sugerir isso sozinho.
Mike Seymour
9
observação secundária: NAN é um float, não um double. link
orion elenzil
23

Como outros indicaram, você está procurando, std::numeric_limits<double>::quiet_NaN()embora eu deva dizer que prefiro os documentos cppreference.com . Especialmente porque esta afirmação é um pouco vaga:

Significativo somente se std :: numeric_limits :: has_quiet_NaN == true.

e foi simples descobrir o que isso significa neste site, se você verificar a seção std::numeric_limits::has_quiet_NaNque diz:

Esta constante é significativa para todos os tipos de ponto flutuante e é garantida como verdadeira se std :: numeric_limits :: is_iec559 == true.

que, como explicado aqui se truemeios a sua plataforma suporta IEEE 754padrão. Este tópico anterior explica que isso deve ser verdade para a maioria das situações.

Shafik Yaghmour
fonte
9

Isso pode ser feito usando numeric_limits em C ++:

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

Estes são os métodos que você provavelmente deseja examinar:

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.
languitar
fonte
6
+1. A Wikipedia tem algumas informações sobre NaN silencioso e sinalização NaN .
Drew Noakes em
1

É possível atribuir um NaN a um double ou float em C ...?

Sim, desde C99, (C ++ 11) <math.h>oferece as funções abaixo:

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

que são como suas strtod("NAN(n-char-sequence)",0)contrapartes e NANpara atribuições.

// 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);

Resultado da amostra: (dependente da implementação)

(7ff8000000012345)
(fff000000006789a)
(7ff8000000000000)
chux - Reintegrar Monica
fonte
Quais são as diferenças entre as saídas para diferentes strings? Qual devemos usar no código numérico típico?
quant_dev