2012-03-08 31 views
13

Tengo una aplicación en la que algún componente ocasionalmente inserta un qNaN en un flujo de datos grande, lo que invalida todo el procesamiento (FFT en un vector que contiene un solo qNaN produce una salida todo-qNaN). Ahora me gustaría atrapar ese componente en el acto y descubrir por qué lo está haciendo.Reventado silencioso NaN

Para esto, necesitaría de alguna manera hacer que todos los NaN señalicen durante la depuración. ¿Hay alguna manera de hacerlo, con una CPU x64 ejecutando código de 32 bits?

+1

No es exactamente un duplicado, pero hay muchos detalles http://stackoverflow.com/questions/570669/checking-if-a-double-or-float-is-nan-in-c – user7116

+0

Otra pregunta con buenos detalles http : //stackoverflow.com/questions/2247447/usefulness-of-signaling-nan – user7116

+0

Relacionado: [¿Puedo hacer que gcc me diga cuándo un cálculo da como resultado NaN o inf en tiempo de ejecución?] (http://stackoverflow.com/questions/2941611/can-i-make-gcc-tell-me-when-a-calculate-results-in-nan-or-inf-at-runtime/20973509) – legends2k

Respuesta

20

Si desea realizar todas NANS, se desborda, y zerodivides señalización durante la depuración, es posible.

Para gcc:

#include <fenv.h> 

#ifndef NDEBUG 
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); 
#endif 

Para Visual Studio (no probado):

#include <float.h> 

#ifndef NDEBUG 
_clearfp(); 
_controlfp(_controlfp(0, 0) & ~(_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW), 
      _MCW_EM); 
#endif 

Referencias: Microsoft, gcc.


Estas funciones permiten atrapar o bien NaNs, producida por operaciones de punto (desbordamientos, zerodivides, operaciones no válidos) flotante, o cambio, los SNAN utiliza como entrada para alguna operación de punto flotante. No permiten atrapar qNaNs, utilizados como entrada para la operación de punto flotante. Para tales qNaNs, la única forma de encontrarlos es verificar cada valor individualmente (ver la respuesta de Luchian Grigore).

lo tanto, si el componente, que inserta un qNaN está en el mismo programa, eran que se desea capturar, o si este componente está en programa separado, pero tiene sus códigos fuente, simplemente permitir excepciones FP con feenableexcept()/_controlfp() . De lo contrario, verifique cada valor en la secuencia de datos entrante con isnan() (C++ 11) o con x != x.

+0

¿Lo pones en el archivo de implementación? –

+0

@LuchianGrigore, sí, simplemente llama a esto desde main(). –

+0

Hm, todavía no recibió una excepción, pero aceptó ya que me puso en el camino correcto con la depuración. –

7

Dudo que haya una manera de poner un punto de interrupción de datos en toda la memoria para capturar todosNaNs.

buscaría el código que se inserta en el vector y prueba para NaN allí:

if (x != x) 
    assert(!"NaN detected"); 
+2

¿Hay alguna razón por la que no haya puesto la condición en el 'assert' en sí mismo? –

+0

@LightnessRacesinOrbit Lo pensé, pero es más legible para un ojo no entrenado como este. –

+0

De acuerdo, copie eso. –