我有一个应用程序,在其中一些组件偶尔会在大型数据流中插入qNaN,这将使整个处理失效(对包含单个qNaN的向量进行FFT会导致所有输出为qNaN)。现在我想在其中捕捉该组件,并找出它为什么这样做。
为此,我需要在调试期间使所有NaN值都是信号类型。在使用执行32位代码的x64 CPU的情况下,是否有方法可以做到这一点?
我有一个应用程序,在其中一些组件偶尔会在大型数据流中插入qNaN,这将使整个处理失效(对包含单个qNaN的向量进行FFT会导致所有输出为qNaN)。现在我想在其中捕捉该组件,并找出它为什么这样做。
为此,我需要在调试期间使所有NaN值都是信号类型。在使用执行32位代码的x64 CPU的情况下,是否有方法可以做到这一点?
如果您想在调试期间将所有NaN、溢出和零除法设置为信号,请注意以下方法。
对于gcc:
#include <fenv.h>
#ifndef NDEBUG
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
#endif
对于Visual Studio(未经测试):
#include <float.h>
#ifndef NDEBUG
_clearfp();
_controlfp(_controlfp(0, 0) & ~(_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW),
_MCW_EM);
#endif
这些函数可以捕获由浮点操作(溢出、零除、无效操作)产生的NaN,或被用作某些浮点操作输入的sNaN。它们无法捕获用作浮点操作输入的qNaN。对于这样的qNaN,唯一的方法就是逐个检查每个值(请参见Luchian Grigore的答案)。
因此,如果插入qNaN的组件与您要捕获的程序在同一个程序中,或者如果该组件在单独的程序中,但您拥有其源代码,请使用feenableexcept()
/_controlfp()
启用FP异常。否则,请使用isnan()
(C++11)或x != x
检查传入数据流中的每个值。
我怀疑没有一种方法可以在整个内存中设置数据断点来捕获所有的NaN。
我会寻找插入到vector
中的代码,并在那里测试是否为NaN
:
if ( x != x )
assert(!"NaN detected");
assert
语句中呢? - Lightness Races in Orbit