2012-03-08 10 views
13

大きなデータストリームに一部のコンポーネントがqNaNを挿入することがあり、処理全体を無効にするアプリケーションがあります(単一のqNaNを含むベクトルのFFTはすべてqNaN出力になります)。今、私はその行為の中でそのコンポーネントを見つけ出し、それがなぜそれをしているのかを知りたいと思います。静かなトラップNaN

このため、デバッグ中にすべてのNaNをシグナリングする必要があります。 x64 CPUが32ビットコードを実行するので、そうする方法はありますか?

+1

正確には重複していませんが、詳細はたくさんあります。http://www.stackoverflow.com/questions/570669/checking-if-a-double-or-float-is-nan-in-c – user7116

+0

もう少し詳しくはhttp ://stackoverflow.com/questions/2247447/usefulness-of-signaling-nan – user7116

+0

関連:[実行時に計算結果がNaNまたはinfになったときにgccに通知できますか?](http://stackoverflow.com/questions)/2941611/can-i-make-gcc-tell-me-a-計算結果のランタイム/ 20973509) – legends2k

答えて

20

オーバーフローし、デバッグの際にシグナルzerodivides、それが可能です。 gccのために

#include <float.h> 

#ifndef NDEBUG 
_clearfp(); 
_controlfp(_controlfp(0, 0) & ~(_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW), 
      _MCW_EM); 
#endif 

参考文献:MicrosoftgccのVisual Studio(テストされていない)のために

#include <fenv.h> 

#ifndef NDEBUG 
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); 
#endif 


これらの機能は、いくつかの浮動小数点演算への入力として使用される小数点演算(オーバフロー、zerodivides、無効操作)、またはsNaNsを浮遊させることによって製造さのNaN、いずれかをキャッチすることを可能にします。浮動小数点演算への入力として使用されるqNaNをキャッチすることはできません。そのようなqNaNについては、それらを見つける唯一の方法は、個々の価値を個別にチェックすることです(Luchian Grigoreの答えを参照)。

はqNaNを挿入コンポーネントは、同じプログラムであるのであれば、あなたはそれをキャッチしたいた、またはこのコンポーネントが別のプログラムである、しかし、あなたはそのソースコードを持っている場合は、ちょうどfeenableexcept()/_controlfp()とFP例外を有効にします。それ以外の場合は、受信データストリーム内のすべての値をisnan()(C++ 11)またはx != xでチェックします。

+0

これを実装ファイルに入れますか? –

+0

@LuchianGrigore、はい、これをmain()から呼び出すだけです。 –

+0

Hm、まだ例外はありませんでしたが、それはデバッグで正しい軌道に乗るように受け入れています。 –

7

私はすべてNaNsをキャッチするために、すべてのメモリ上のデータブレークポイントを配置する方法があります疑います。

私はそこNaNためvectorとテストに挿入するコードを探したい:あなたはすべてのNaNを作りたい場合は、

if (x != x) 
    assert(!"NaN detected"); 
+2

あなたは 'assert'自体に条件を入れなかった理由はありますか? –

+0

@LightnessRacesinOrbit私はそれについて考えましたが、このように未熟な目で見やすくなりました。 –

+0

それをコピーしてください。 –