2010-09-01 28 views
28

Voy a hacer algunos cálculos matemáticos con C++. El número de punto flotante de entrada es un número válido, pero después de los cálculos, el valor resultante es NaN. Me gustaría rastrear el punto donde aparece el valor de NaN (posiblemente usando GDB), en lugar de insertar una gran cantidad de isNan() en el código. Pero descubrí que incluso un código como este no activará una excepción cuando aparezca un valor de NaN.Cómo rastrear un NaN en C++

double dirty = 0.0; 
double nanvalue = 0.0/dirty; 

¿Alguien podría sugerir un método para rastrear el NaN o convertir un NaN en una excepción?

+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

+0

También http://stackoverflow.com/questions/5393997/stopping-the-debugger-when-a-nan-floating-point -number-is-produced – Riot

Respuesta

7

En Visual Studio se puede utilizar la función _controlfp para establecer el comportamiento de cálculos de coma flotante (vea http://msdn.microsoft.com/en-us/library/e9b52ceh(VS.80).aspx). Tal vez haya una variante similar para su plataforma.

+0

Hola, gracias por tu respuesta. Desafortunadamente mi plataforma es GCC4.1, Centos 5.5 Linux. Todavía estoy tratando de descubrir cómo lograr lo mismo en Linux con GCC – user1492900

+2

feenableexcept() parece funcionar, ahora estoy tratando de rastrear mi programa con esto. http://gcc.gnu.org/onlinedocs/gcc-3.1.1/g77/Floating-point-Exception-Handling.html # Punto flotante% 20Exception% 20Handling – user1492900

0

Se puede habilitar el llamado "NaN de señalización". Eso debería permitir fácilmente que el depurador encuentre la posición correcta.

a través de Google, he encontrado este para permitir NaNs señalización en C++, ni idea de si funciona:

std::numeric_limits::signaling_NaN();

Usefulness of signaling NaN?

+2

Esa expresión se evalúa como NaN de señalización, pero creo que pagedown está más interesado en forzar una excepción de coma flotante para operaciones que devuelven NaN, que probablemente sería una opción de compilador específica de plataforma o configuración de tiempo de ejecución del Procesador FP –

+0

Ah, lo siento. Lo entendí como hacer toda la señalización de NaN. –

+0

Muchas gracias. Mi plataforma es GCC4.1, Centos 5.5 Linux Voy a echar un vistazo a las opciones del compilador :) – user1492900

35

Dado que usted menciona el uso de GDB, he aquí una solución que funciona con gcc - desea que las funciones definidas en fenv.h:

#include <fenv.h> 
#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    double dirty = 0.0; 

    feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT); // Enable all floating point exceptions but FE_INEXACT 
    double nanval=0.0/dirty; 
    printf("Succeeded! dirty=%lf, nanval=%lf\n",dirty,nanval); 
} 

ejecutar el programa anterior produce la salida "punto flotante excepción". Sin la llamada a feenableexcept, el "éxito!" mensaje está impreso.

Si tuviera que escribir un controlador de señal para SIGFPE, podría ser un buen lugar para establecer un punto de interrupción y obtener el rastreo que desee. (Descargo de responsabilidad: no lo he probado!)

+0

Muchas gracias – user1492900

+2

El error se encuentra :) – user1492900

+13

Gracias por esta respuesta, solo quiero señalar que al habilitar * todas * las excepciones de punto flotante también permite FE_INEXACT que ocurre muy a menudo (incluso para: float f = 0.1) y la depuración se vuelve imposible. Es mucho mejor usar feenableexcept (FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); – DarioP

1

Algunas notas sobre la programación de punto flotante se pueden encontrar en http://ds9a.nl/fp/ incluyendo la diferencia entre 1/0 y 1.0/0, etc., y qué es un NaN y cómo actúa.

+0

Muchas gracias – user1492900

Cuestiones relacionadas