如何在gcc中检查安静的NaN?

时间:2012-10-04 08:13:34

标签: c gcc floating-point nan

我知道if(value == value)是否有诀窍但在我的应用程序中我有超过50个变量需要检查和检查每个变量有点乏味且可能效率低下。理想情况下,我正在寻找的是在子程序结束之前我可以调用一个函数(如果这样的函数存在)并且它将返回1或0.我有一种感觉因为在汇编中存在这样的函数可以检查全局浮动点状态寄存器。 如果不是这样的话那么有没有比为每个浮点变量轮询值==值更好的方法呢?

3 个答案:

答案 0 :(得分:3)

您可以使用isnanfpclassify。两者都是C99的标准。

关于你的问题,如果你的变量都在一些常见的地方声明,我会写一个小工具把这些声明变成一串isnan个调用。

答案 1 :(得分:3)

一般来说,没有办法问“我的数据中某处有NaN吗?”

检查处理器的浮点寄存器不足以回答这个问题,因为浮点对象的值保存在内存中以及计算的各个点的寄存器中,特别是如果你有五十个。

有一种方法可以询问“是否发生了无效的操作异常?”C标准的第7.6条规定了浮点环境访问,通过宏和函数定义。在各种编译器中,对它的支持可能很差。基本上,您可能希望使用feclearexcept清除FE_INVALID,执行一些计算,并测试是否已使用fetestexcept设置FE_INVALID。您还需要设置“#pragma STD FENV_ACESS on”。

这只会测试计算过程中是否发生无效操作异常。它不会测试输入数据中是否存在NaN。它不会测试在没有无效操作异常的情况下生成的NaN。

答案 2 :(得分:0)

这样的事情可能会有所帮助吗?

void registerAddVariable(double *x) {
  APPEND(x); // append to some global linked list
}
void registerRemoveVariable(double *x) {
  REMOVE(x); // remove from same global linked list
}
void registerDebug() {
  list = head; 
  while(list) {
    if (isnan(*(list->variable))) {
      output(list);
    }
    list = list->next;
  }
}

void myfun() {
  double variable; registerAddVariable(&variable);
  ...
  registerDebug();
  ....
  registerRemoveVariable(&variable);
}