C言語関係掲示板

過去ログ

No.45. 実数の誤差


はじめましてです。
どうして結果のようになるのですか?
教えてください。
#include<stdio.h>
int main(void){
     double i;
     for(i=0;i<=1;i+=0.1)
          printf("%1.18f\n",i);
     return(0);
}
結果
0.000000000000000000
0.100000000000000006
0.200000000000000011
0.300000000000000044
0.400000000000000022
0.500000000000000000
0.599999999999999978
0.699999999999999956
0.799999999999999933
0.899999999999999911
0.999999999999999889


やまさん、こんにちは、ともじです。

> どうして結果のようになるのですか?
> 教えてください。

ご存知だと思いますが、コンピュータではデータは全て1/0の信号で扱われますよね。
内部的な数値処理は2進数で行っているわけです。
整数の場合には、問題なく2進数で処理できますが、実数の場合には、
http://www9.plala.or.jp/sgwr-t/c_sub/dtgata.html
に示すように、符号部、指数部、仮数部に分けて2進数に変換して処理をしています。

0.25(10進数) ->0.01(2進数) のように循環にならずに変換できる場合はいいの
ですが、大抵の実数は2進数に変換すると、循環2進小数になってしまいます。
(例) 0.1(10進数) -> 0.00011001100110011001100・・・
この循環2進小数を決められたバイト数のメモリに格納するわけですから、
どうしても誤差(丸め誤差といいます)が生じます。

やまさんが示すプログラムがきっかりとした値にならないのは、丸め誤差による
もので、コンピュータのデータが2進数で処理をしている限り、仕方のないこと
なのです。

ここで注意しなければならないのは、
for ( i = 0; i != 1; i += 0.1 )  のような記述をしてはいけないという点です。
i==1にはならないので、無限ループになってしまいます。


なるほど。そういうことだったんですね。
ともじさんありがとうございます。

戻る


「初心者のためのポイント学習C言語」 Last modified:2001.10.5
Copyright(c) 2000-2002 TOMOJI All Rights Reserved