dポイントプレゼントキャンペーン実施中!

double i;

for(i = 1.0; (int)i<=10; i+=0.1){
printf("%lf %d\n",i,(int)i);
}

上のようなソースで 1.0 から 10.9 まで 0.1 刻みで小数を表示しようとしたのですが、
条件式

(int)i<=10

にも関わらず出力結果に 11.0 が含まれてしまうのは何故でしょうか。

A 回答 (3件)

double型のコンピュータ内での内部表現は2進数(基数が2の浮動小数点数)です。



0.1は10進数ではきりの良いという小数ですが
2進数では無限小数(循環小数)になり
無限に桁を保持することはできないので
途中で丸められてしまいます。(丸めは四捨五入と同等の処理です。)
ここで誤差が発生するため思っているような出力結果にならなかったのでしょう。

試しにそのコードを私の環境で実行し、
printfで小数点以下15桁まで出力してみたところ
最後の11.0は正確には

10.999999999999979

でした。


参考:
http://e-words.jp/w/E4B8B8E38281E8AAA4E5B7AE.html
http://ja.wikipedia.org/wiki/%E6%B5%AE%E5%8B%95% …
    • good
    • 0
この回答へのお礼

コードを実行までして頂き本当にありがとうございます。
とても分かりやすいご説明でした。
丸め誤差を考慮しつつ、これからは加算の順序も工夫していきたいと思います。

お礼日時:2006/05/28 04:40

演算誤差のため、最後が11より'ほんの少し'でも小さかったら、


intにキャストすると切り捨てられて10になります。
    • good
    • 0
この回答へのお礼

画面に表示される数字の小数部分よりも更に精度の高いところで誤差が発生するんですね。
今後は気をつけます。
ご回答ありがとうございました。

お礼日時:2006/05/28 04:53

 doubleなどの浮動小数点型は値によっては厳密に正確な値を表現することが出来ません。


 特に 0.1などの正確に表現できない値を加算・減算を繰り返すと値の精度は計算の度に劣化して行きます。

 このあたりは「浮動小数点」「誤差」で検索してみると解説しているページが幾つも見つかると思います。

 このケースの場合、printfによる表示では 11.0になっていても実際の iの値は 10.99999999999と限りなく 11に近いけれども 11未満の値になっていると思われます。

 for文を (ii=1.0; ii<10.91; ii+=0.1) にすれば 11.0正しく表示されると思いますが、後半の値は若干の誤差を含んでいるので、計算にはほとんど支障はないはずですが、比較などでは注意が必要です。
    • good
    • 0
この回答へのお礼

浮動小数点型では0.1はキリ良く認識されてないんですね。勉強になりました。
ご回答ありがとうございました。

お礼日時:2006/05/28 04:49

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!