3

現在、一部の計算で Raytracer "Engine" に関する問題が発生しています。

  info->eyex = -1000.0;
  info->eyey = 0.0;
  printf("%f et %f et %f et %f et %f\n", info->eyex, info->vx, info->eyey, info->vy, info->vz);

たとえば、そのコードでは、値は適切に見えますがinfo->eyex-nanエラーが発生します。

前に値をリセットしたので、変です。

4

2 に答える 2

4

私の精神的感覚は、それが本来あるべきであるとしてではなく、 としてeyex宣言されていることを教えてくれます。-1000.0 を割り当てると、整数 -1000 に切り捨てられます (コンパイラここで警告を表示する必要があります)。これは、2 の補数表記を使用して 0xFFFFFC18 としてバイナリで表されます。同様に、も整数であると仮定すると、その値 0 はバイナリで 0x00000000 として表されます。intdoubleeye

eyexeyey、およびその他のパラメータを に渡すとprintf、それらはスタックにプッシュされ、アドレスが増加してメモリに配置されます。したがって、サブルーチンを呼び出す命令の直前ではcall、スタック フレームは次のようになります。

<top of stack>
0xFFFFFC18   ; eyex
(4-8 bytes)  ; vx
0x00000000   ; eyey
(4-8 bytes)  ; vy
(4-8 bytes)  ; vz

フォーマット指定子をprintf見ると、 「スタックから 8 バイトを取り出し、それらを値%fとして解釈し、その値を出力する」と書かれています。したがって、値 0xFFFFFC18xxxxxxxx が表示されます。ここで、xxxxxxxxx は の値です。その値に関係なく、これは NaN のIEEE 754表現、つまり「非数」です。これには符号ビットが設定されているため、実装によってはこれを「負の NaN」として解釈することを選択する場合がありますが、これは通常の NaN と同じセマンティクスを持ちます。doubledoubleinfo->vx

コンパイラは、間違ったタイプの引数を に渡していることも警告しているはずprintfですdouble。GCC はこれらの警告を-Wallで有効にします。これを有効にすることを強くお勧めします。

したがって、解決策はeyex型であることを宣言することですdouble(そして、おそらく他の変数も型であると宣言しますdouble)。または、 et alの定義を制御しない場合eyex(たとえば、サードパーティ ライブラリの構造の一部であるため)、代わりに行うべきことは、次のように%d印刷する修飾子を使用してそれらを印刷することです。また、-1000.0 や 0.0 などの浮動小数点値ではなく%f、-1000 や 0 などの整数値を割り当てる必要があります。

于 2011-07-01T20:01:03.500 に答える
2

これを確認するだけです。しかし、何がその行動を引き起こすのか正確にはわかりません。printf はコンパイル時に最適化され、フォーマット文字列が分析されます。おそらく、変数について何かを (間違って) 想定しているのでしょう。%f は double と float に対して機能するはずですが、常に機能するとは限りません (少なくとも、私が使用している gcc 4.4.5 では)。

値を別の変数に割り当ててから、それを printf に渡してみてください。醜いですが、それで問題は解決しました。

于 2011-07-01T19:23:00.993 に答える