3

私は、FORTRANで生成されたREAL配列からfloatを抽出し、それをログに記録するためにストリームに挿入する単純なコードを持っています。これは最初の30の場合に機能しますが、31日に「浮動小数点の無効な操作」でクラッシュします。

コードは次のとおりです。

int FunctionDeclaration(float* mrSwap)
{
...
float swap_float;
stringstream message_stream;
...
swap_float = *(mrSwap+30-1);
...
message_stream.clear();
message_stream <<  30 << "\t" << swap_float << "\tblah blah blah \t";

デバッグ時、クラッシュ前のインスタンスのswap_floatの値(上記の最後の行)は1711696.3です。これは、この時点までのほとんどの値よりもはるかに大きいことを除けば、特に特別なことはありません。

また、message_streamをcerrに置き換えてみましたが、同じ問題が発生しました。私はこれまで、cerrはほとんど破壊できないと信じていましたが、単純なフロートでどのように破壊できるのでしょうか。

編集:

コメントありがとうございます:mrSwapの宣言を追加しました。mrSwapの長さは約200なので、私は終わりから遠く離れています。それは私のコントロールの外に入力され、個々のエントリは入力されないかもしれません-しかし私の理解の限りでは、これはswap_floatがランダムなfloatに設定されることを意味しますか?

4

2 に答える 2

3

個々のエントリには値が入力されない場合がありますが、私の理解では、これは swap_float がランダムなフロートに設定されることを意味しますか?

強調しないでください。IEEE 浮動小数点数の特定のビット パターンは、無効な数値を示します。たとえば、オーバーフローした算術演算の結果や無効な数値 (0.0/0.0 など) です。ここで不可解なことは、デバッガーが数値を有効なものとして受け入れるように見えますが、そうでcoutはないということです。

のビット レイアウトを取得してみてくださいswap_float。32 ビット システムの場合:

int i = *(int*)&swap_float;

次にi、16 進数で出力して、表示された内容をお知らせください。

追加して更新: Mike のコメントから、i=1238430338、16 進数で 49D0F282 です。これは正確に 1711696.25 に等しい有効な浮動小数点数です。だから、何が起こっているのかわからない、怖い。私が提案できる唯一のことは、コンパイラが無効な浮動小数点数をmrSwap配列から浮動小数点レジスタバンクに直接ロードしている可能性があるということswapFloatです。swapFloatしたがって、デバッガーはの真の値を使用できません。これを確認するには、試してください

int j = *(int*)(mrSwap+30-1);

そして、あなたが見たものを教えてください。

追加のために再度更新:別の可能性は、遅延浮動小数点トラップです。浮動小数点コプロセッサ (最近では CPU に組み込まれています) は、不正な操作のために浮動小数点割り込みを生成しますが、次の浮動小数点操作が試行されるまで割り込みは認識されません。したがって、このクラッシュは、以前の浮動小数点演算の結果である可能性があり、どこにでもある可能性があります。頑張ってください...

于 2012-05-09T11:57:08.547 に答える