Как отследить NaN в C++
Я собираюсь сделать некоторые математические вычисления с использованием C++ . Входное число с плавающей запятой является действительным числом, но после вычислений результирующее значение равно NaN. Я хотел бы проследить точку, где появляется значение NaN (возможно, с использованием GDB), вместо того, чтобы вставлять много isNan()
в код. Но я обнаружил, что даже такой код не будет вызывать исключение при появлении значения NaN.
double dirty = 0.0;
double nanvalue = 0.0/dirty;
Может ли кто-нибудь предложить метод для отслеживания NaN или превращения NaN в исключение?
4 ответа
В Visual Studio вы можете использовать функцию _controlfp, чтобы установить поведение вычислений с плавающей запятой (см. http://msdn.microsoft.com/en-us/library/e9b52ceh(VS.80).aspx). Может быть, есть аналогичный вариант для вашей платформы.
Поскольку вы упоминаете об использовании GDB, вот решение, которое работает с GCC - вы хотите функции, определенные в 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);
}
Запуск вышеуказанной программы выдает "Исключение с плавающей точкой". Без вызова feenableexcept
"Успешно!" сообщение распечатано
Если бы вы должны были написать обработчик сигнала для SIGFPE
, это может быть хорошим местом для установки точки останова и получения требуемой трассировки. (Отказ от ответственности: не пробовал!)
Некоторые заметки по программированию с плавающей запятой можно найти на http://ds9a.nl/fp/ включая разницу между 1/0 и 1.0/0 и т. Д., А также что такое NaN и как он действует.
Можно включить так называемую "сигнализацию NaN". Это должно легко позволить отладчику найти правильную позицию.
Через Google я нашел это для включения сигнализации NaNs в C++, не знаю, работает ли это:
std::numeric_limits::signaling_NaN();