2011-09-01 22 views
16

Tengo un pequeño programa que realiza la división de punto flotante por cero, por lo que espero SIGFPE.División por cero no arroja SIGFPE

#include <sys/types.h> 
#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <iostream> 

void signal_handler (int signo) { 
    if(signo == SIGFPE) { 
     std::cout << "Caught FPE\n"; 
    } 
} 

int main (void) { 
    signal(SIGFPE,(*signal_handler)); 

    double b = 1.0; 
    double c = 0.0; 
    double d = b/c; 
    std::cout << "d = "<< d << std::endl; 
    return 0; 
} 

En realidad, me dieron el siguiente resultado:

d = inf 

versión de gcc 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)

¿Qué debo hacer para tirar SIGFPE en este ¿caso? ¿De qué factores depende el comportamiento de operación FP (indicadores de compilación/tipo de CPU, etc.)?

Gracias

+2

Esto debería ser bastante estándar si tiene flotadores IEEE. – Ingo

+0

Pregunta similar: [¿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) – sleske

Respuesta

6

Para números en coma flotante, puede cambiar este comportamiento configurando la palabra de control FPU. Eche un vistazo here

+0

Sé sobre la palabra de control de FPU. Se puede establecer con _controlfp() en la plataforma MS. ¿Existe el equivalente POSIX para esta función? –

+1

@Yuri: vea si su archivo de inclusión estándar '' define 'fesettrapelable'. Esto no es estándar, pero está ampliamente disponible.En Linux, usa 'feenableexcept' - pero necesitas' #define _GNU_SOURCE' antes de '#include '. –

+1

@Yuri S. Cherkasov Está en fpu_control.h. Compruebe aquí: http://www.christian-seiler.de/projekte/fpmath/ – Oleg

9

que sólo recibe una señal si se realiza una división entera por cero. Para los números de coma flotante, la división por cero está bien definida.

Esto realmente se explica bastante bien en el Wikipedia article.

+0

No estoy criticando su respuesta, simplemente criticando esa inanidad en el estándar IEEE. Piensa cuánto sentido tiene esto: obtienes una * excepción de punto flotante * si realizas una división * entera * por cero. De forma predeterminada, no obtiene una excepción de punto flotante si realiza un punto flotante dividido por cero. Las personas que hacen informática numérica para ganarse la vida tienden a odiar que este es el comportamiento predeterminado. Peor aún, no existe un estándar para que obtengamos el comportamiento deseado. División por cero, etc., son casi siempre una señal de que algo salió mal. –

+5

Leyendo la fuente beats wikipedia: http://754r.ucbtest.org/standards/754.pdf: 7.2: "Si el divisor es cero y el dividendo es un número finito distinto de cero, entonces se debe señalar la excepción de división por cero El resultado, cuando no se produce una trampa, debe ser un INFINITO (6.3) correctamente firmado. ". Y el capítulo 8 nos dice que el usuario debería poder especificar un manipulador de trampas, que se genera cuando ocurre alguna de las excepciones en ch.7. –

+0

Eso es interesante, pero el propósito es atrapar tales situaciones, porque la división por cero es una operación ilegal en mi contexto. –

4

No obtiene una señal porque el comportamiento predeterminado en la mayoría de las máquinas es contaminar sus datos con NaN (no un número) e infinitos. Debe habilitar las excepciones de coma flotante, y cómo lo hace es específico de la máquina. Mire el encabezado del sistema fenv.h, si tiene uno. La función fesettrapenable permite capturar excepciones de coma flotante en muchas máquinas.

Desafortunadamente, no existe una función estándar para activar el tratamiento de excepciones de punto flotante.

Cuestiones relacionadas