• 締切済み

お願いします!!

はじめまして、UAです。REDHAT 7.3 と 9をしようして、GCC3.2を使用してプログラムを書いているのですが、思い通りに動作しません。いろいろ調べて見たのですが、納得がいく答えが見つかりません。機種依存であるなら仕方ないのですが、以下のプログラムの実行についてアドバイスしていただけないでしょうか? --------foo.c--------------------- #include <stdio.h> int main() { double d = 0.3; printf("%d ",(int)(d * 10.0)); return 0; } foo.c はdoubleをINTにキャストしています。この式を判断したら、3の値が求まるはずなのですが結果は --------result------------ 2 となってしまいます。  この問題で、GCCで最適化をかけてコンパイルすると、正しい値が表示されるのですが、次のようにして、配列を利用して値を評価すると、エラーになります。つまり、dの値を0.1から、0.9まで評価して、値を表示させる。 ------foo.c------------v2 #include <stdio.h> int main() { int i; double d[] = {0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9}; for(i=0;i < 9;i++) printf("%d ",(int)(d[i] * 10.0)); return 0; } これを実行すると、-O(最適化オプション)をつけて、さらに、-ffloat-storeをつけたとしても、1 2 3 ...と表示されずに、1 2 2 3 4 5 56 8 9と表示されてしまいました。  これは、どうしておこるのでしょうか? 誰かアドバイスをお願いいたします。

みんなの回答

  • nightowl
  • ベストアンサー率44% (490/1101)
回答No.2

こんにちは。原因は浮動小数点数の誤差ですね。 tatsu99 さんのおっしゃる通り、最適化すると 定数の畳み込みが行われるのでしょう。 望み通りの結果を得るには、printf のフォーマットを変更します。 printf("%g ", d[i] * 10.0); /* キャストは不要 */ もしくは、math.h をインクルードして printf("%d ",(int)rint(d[i] * 10.0)); とし、コンパイル時に数学ライブラリをリンクしてください。 $ gcc -o foo foo.c -lm

参考URL:
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/nearbyint.3.html
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

-Sオプションをつけるとアセンブラのソースが出力されます。 最初のソースを最適化オプション-O1-Sでアセンブラに落とすと、整数の3をprintfする命令が出力されます。一方、最適化オプションをつけないで、アセンブラにおとすと、0.3×10をそのまま計算します。 従って、実行結果が最適化した場合は3になり、最適化しない場合は、2になります。 二番目のソースを同様にアセンブラに落とした場合、 最適化をした場合でも、しない場合でも、テーブルの値(0.1,0.2等)×10の計算を行っています。 従って、この場合は、1,2,3,4,5・・・のような結果は得られません。 以上のことからgccの最適化O1を行った場合、0.3*10は3であることが明白なので、いきなり3を印字しているようです。

関連するQ&A

専門家に質問してみよう