significa que isnan c++ floating-point nan

que - isnan std c++



¿Usando NaN en C++? (6)

Puede escribir un NaN de señalización en una variable sin activar una excepción con algo como esto (nb: no probado)

void set_snan( double &d ) { long long *bits = (long long *)&d; *bits = 0x7ff0000080000001LL; }

Funcionará en la mayoría de los lugares, pero no, no es 100% portátil.

¿Cuál es la mejor manera de usar NaNs en C ++?

Encontré std::numeric_limits<double>::quiet_NaN() y std::numeric_limits<double>::signaling_NaN() . Me gustaría utilizar signaling_NaN para representar una variable no inicializada de la siguiente manera:

double diameter = std::numeric_limits<double>::signaling_NaN();

Esto, sin embargo, señala (genera una excepción) en la asignación. Quiero que haga una excepción sobre el uso, no sobre la asignación.

¿Hay alguna forma de utilizar signaling_NaN sin generar una excepción en la asignación? ¿Existe una buena alternativa portátil a signaling_NaN que genere una excepción de punto flotante cuando se usa?


Bueno, cuidando la definición de NaN silencioso y de señalización, realmente no puedo distinguir nada.

Puede usar el código que se usa en esas funciones usted mismo, quizás impida una excepción de esa manera, pero al no ver ninguna excepción en esas dos funciones, creo que podría estar relacionado con otra cosa.

Si quiere asignar directamente el NaN:

double value = _Nan._Double;


Lo que NAN de señalización significa es que cuando la CPU se encuentra con él, se dispara una señal (de ahí el nombre). Si desea detectar variables no inicializadas, al subir el nivel de advertencia en su compilador generalmente se detectan todas las rutas que usan valores no inicializados. De lo contrario, puede usar una clase contenedora que almacene un booleano que diga si el valor está inicializado:

template <class T> class initialized { T t; bool is_initialized; public: initialized() : t(T()), is_initialized(false) { } initialized(const T& tt) : t(tt), is_initialized(true) { } T& operator=(const T& tt) { t = tt; is_initialized = true; return t; } operator T&() { if (!is_initialized) throw std::exception("uninitialized"); return t; } };


Respuesta simple: haga algo como esto en el archivo de encabezado y úselo en cualquier otro lugar:

#define NegativeNaN log(-1)

Si deseas hacer algún tipo de manipulaciones sobre ellos, mejor escribe alguna función de envoltura extendida alrededor de exp() como extended_exp() y así sucesivamente.


Después de investigar esto un poco más, parece que signaling_NaN es inútil según lo previsto. Si las excepciones de coma flotante están habilitadas, llamarlas cuenta como procesar un NaN de señalización, por lo que inmediatamente genera una excepción. Si las excepciones de punto flotante están deshabilitadas, entonces el procesamiento de un NaN de señalización automáticamente lo degrada a un NaN silencioso, por lo que signaling_NaN no funciona de ninguna manera.

El código de Menkboy funciona, pero tratar de usar NaN de señalización se encuentra con otros problemas: no hay forma portátil de habilitar o deshabilitar excepciones de punto flotante (como se alude aquí y aquí ), y si se basa en excepciones habilitadas, el código de un tercero puede deshabilítelos (como se describe aquí ).

Entonces parece que la solución de Motti es realmente la mejor opción.


Su implementación en C ++ puede tener una API para acceder al entorno de punto flotante para probar y borrar ciertas excepciones de coma flotante. Ver mi respuesta a una pregunta relacionada para más información.