¿Constante de C / C ++ NaN (literal)?

110

¿Es posible asignar un NaNa a doubleo floaten C / C ++? Al igual que en JavaScript que hace: a = NaN. Entonces, más tarde, puede verificar si la variable es un número o no.

exebook
fuente
Aquí muestro cómo se ven varios NaN cuando se generan por diferentes medios: stackoverflow.com/questions/18118408/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

153

En C, NANse declara en <math.h>.

En C ++, std::numeric_limits<double>::quiet_NaN()se declara en <limits>.

Pero para verificar si un valor es NaN, no puede compararlo con otro valor de NaN. En su lugar, utilice isnan()desde <math.h>en C o std::isnan()desde <cmath>en C ++.

Mike Seymour
fuente
20
O puede comparar el número consigo mismo: x == xdevuelve falsesif xes NaN.
Archie
7
@ Archie: No creo que eso esté garantizado en ninguno de los idiomas.
Mike Seymour
3
@MikeSeymour No según el estándar del lenguaje, pero hasta donde yo sé, debería funcionar si el compilador afirma ser compatible con IEEE.
Pixelchemist
37
@Pixelchemist: De hecho, es una opción si necesita ofuscación pero no portabilidad. Personalmente, prefiero la portabilidad sin ofuscación, así que no lo sugeriré yo mismo.
Mike Seymour
9
nota menor: NAN es un flotador, no un doble. enlace
orion elenzil
23

Como otros han señalado, está buscando, std::numeric_limits<double>::quiet_NaN()aunque debo decir que prefiero los documentos de cppreference.com . Especialmente porque esta declaración es un poco vaga:

Solo tiene sentido si std :: numeric_limits :: has_quiet_NaN == true.

y fue simple descubrir lo que esto significa en este sitio, si revisa su sección std::numeric_limits::has_quiet_NaNque dice:

Esta constante es significativa para todos los tipos de punto flotante y se garantiza que sea verdadera si std :: numeric_limits :: is_iec559 == true.

el cual como se ha explicado aquí si truemediante su plataforma soporta IEEE 754estándar. Este hilo anterior explica que esto debería ser cierto para la mayoría de las situaciones.

Shafik Yaghmour
fuente
9

Esto se puede hacer usando numeric_limits en C ++:

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

Estos son los métodos que probablemente quiera ver:

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
fuente
6
+1. Wikipedia tiene información sobre NaN silencioso y señalización de NaN .
Drew Noakes
1

¿Es esto posible asignar un NaN a un doble o flotante en C ...?

Sí, desde C99, (C ++ 11) <math.h>ofrece las siguientes funciones:

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

que son como sus strtod("NAN(n-char-sequence)",0)homólogos y NANpara asignaciones.

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

Salida de muestra: (depende de la implementación)

(7ff8000000012345)
(fff000000006789a)
(7ff8000000000000)
chux - Restablecer a Monica
fuente
1
¿Cuáles son las diferencias entre las salidas para diferentes cadenas? ¿Cuál deberíamos usar en un código numérico típico?
quant_dev