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