¿Puedo hacer que gcc me diga cuándo un cálculo da como resultado NaN o inf en tiempo de ejecución?

2 minutos de lectura

avatar de usuario
jordán lewis

¿Hay alguna manera de decirle a gcc que lance un SIGFPE o algo similar en respuesta a un cálculo que da como resultado NaN o (-)inf en tiempo de ejecución, como lo haría para una división por cero?

he probado el -fsignaling-nans bandera, que no parece ayudar.

  • -fsignaling-nans es tiempo de ejecución, no tiempo de compilación.

    – Lira Nuna

    31 de mayo de 2010 a las 6:09

avatar de usuario
marca dickinson

Casi cualquier operación de punto flotante o función de biblioteca matemática que produzca un NaN a partir de entradas que no sean NaN también debe indicar la excepción de punto flotante de “operación no válida”; De manera similar, un cálculo que produce un infinito a partir de entradas finitas normalmente señalará la excepción de punto flotante ‘dividir por cero’ o ‘desbordamiento’. Entonces, desea alguna forma de convertir estas excepciones en un SIGFPE.

Sospecho que la respuesta dependerá en gran medida del sistema, ya que es probable que el control de las trampas y banderas de coma flotante lo proporcione la biblioteca de la plataforma C en lugar de gcc. Pero aquí hay un ejemplo que me funciona, en Linux. utiliza el feenableexcept función de fenv.h. los _GNU_SOURCE define es necesario para que esta función sea declarada.

#define _GNU_SOURCE
#include <fenv.h>

int main(void) {
    double x, y, z;
    feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);

    x = 1e300;
    y = 1e300;
    z = x * y; /* should cause an FPE */

    return 0;
}

Una advertencia: creo que es posible con algunas configuraciones que la excepción no se genere realmente hasta que el próximo operación de punto flotante después de la que (en teoría) debería haberla causado, por lo que a veces necesita una operación de punto flotante sin operación (por ejemplo, multiplicar por 1.0) para activar la excepción.

avatar de usuario
leyendas2k

En MinGW 4.8.1 (GCC para Win32) veo que el feenableexcept no está definido La solución es usar la plataforma Win32 _controlfp por lo tanto:

#undef __STRICT_ANSI__ // _controlfp is a non-standard function documented in MSDN
#include <float.h>
#include <stdio.h>

int main()
{
   _clearfp();
   unsigned unused_current_word = 0;
   // clearing the bits unmasks (throws) the exception
   _controlfp_s(&unused_current_word, 0, _EM_OVERFLOW | _EM_ZERODIVIDE);  // _controlfp_s is the secure version of _controlfp

   float num = 1.0f, den = 0.0f;
   float quo = num / den;
   printf("%.8f\n", quo);    // the control should never reach here, due to the exception thrown above
}

  • Esto no parece funcionar en MinGW 4.6.2 (‘_clearfp()’ no se declaró en este ámbito)

    – Antonello

    3 de noviembre de 2015 a las 15:15

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad