【问题标题】:How to trace a NaN in C++如何在 C++ 中跟踪 NaN
【发布时间】:2011-04-06 15:43:20
【问题描述】:

我将使用 C++ 进行一些数学计算。输入的浮点数是一个有效的数字,但是经过计算,结果是NaN。我想跟踪出现 NaN 值的点(可能使用 GDB),而不是在代码中插入大量 isNan()。但是我发现即使是这样的代码在出现NaN值时也不会触发异常。

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

谁能建议一种方法来跟踪 NaN 或将 NaN 变成异常?

【问题讨论】:

标签: c++ debugging floating-point


【解决方案1】:

既然你提到使用 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,“成功!”消息被打印出来。

如果您要为SIGFPE 编写信号处理程序,那可能是一个好地方 设置断点并获取所需的回溯。 (免责声明:没有尝试过!)

【讨论】:

  • 感谢您的回答,我只想指出启用 all 浮点异常也会启用经常发生的 FE_INEXACT(即使对于:float f = 0.1)和调试变得不可能。使用feenableexcept(FE_DIVBYZERO| FE_INVALID|FE_OVERFLOW)要好得多;
  • 这是一个适用于 OS X 的有用页面,其中不包括feenableexcept:www-personal.umich.edu/~williams/archive/computation/…
【解决方案2】:

在 Visual Studio 中,您可以使用 _controlfp 函数来设置浮点计算的行为(请参阅http://msdn.microsoft.com/en-us/library/e9b52ceh(VS.80).aspx)。也许您的平台有类似的变体。

【讨论】:

  • 您好,谢谢您的回答。不幸的是,我的平台是 GCC4.1 ,Centos 5.5 Linux。我仍在试图弄清楚如何使用 GCC 在 Linux 中实现同样的目标
  • feenableexcept() 似乎工作,我现在正试图用这个来跟踪我的程序。 gcc.gnu.org/onlinedocs/gcc-3.1.1/g77/…
【解决方案3】:

关于浮点编程的一些说明可以在http://ds9a.nl/fp/ 上找到,包括 1/0 和 1.0/0 等之间的区别,以及 NaN 是什么以及它的作用。

【讨论】:

    【解决方案4】:

    可以启用所谓的“信令 NaN”。这应该可以很容易地让调试器找到正确的位置。

    通过谷歌,我发现这是在 C++ 中启用信号 NaN,不知道它是否有效:

    std::numeric_limits::signaling_NaN();

    Usefulness of signaling NaN?

    【讨论】:

    • 该表达式的计算结果为信号 NaN,但我认为 pagedown 更感兴趣的是为返回 NaN 的操作强制浮点异常,这可能是特定于平台的编译器选项,或运行时配置FP 处理器。
    • 对不起。我将其理解为发出所有 NaN 信号。
    • 非常感谢。我的平台是 GCC4.1 , Centos 5.5 Linux 我要去看看编译器选项:)
    猜你喜欢
    • 2020-10-21
    • 1970-01-01
    • 2015-10-29
    • 2013-02-15
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多