for の条件

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
nao

for の条件

#1

投稿記事 by nao » 14年前

独習Cの第4版のp124で質問です!
下のプログラムでforループの条件で変数を整数値に直して10より小さいというようにしているのですが、これはつまり9.9まで表示され、その後は表示されないことになりますよね?
ですが、実行結果では10.0まで表示されてしまいます。
なぜなのでしょうか?
全くわからなかったのでよければお返事もらえるとうれしいです・・・
申し訳ないです。

コード:

#include <stdio.h>

int main(void)
{
	double f;
	for(f=1.0;(int)f<10;f=f+0.1)
	printf("%f  ",f);
	
	return 0;
}

アバター
さかまき
記事: 92
登録日時: 14年前

Re: for の条件

#2

投稿記事 by さかまき » 14年前

printf("%f %d\n",f,(int)f);
で原因がわかります

non
記事: 1097
登録日時: 14年前

Re: for の条件

#3

投稿記事 by non » 14年前

コンピュータ内部では、数値を2進数で扱っていますが、0.1はピッタリした2進数に表すことができず、
循環小数になってしまいます。詳しくは浮動小数点数などで検索してください。従って、誤差が出て
いるために期待したようになりません。
試しに、
printf("%.20f ",f);
のようにして実行してみましょう。
non

アバター
沖 滉均
記事: 237
登録日時: 14年前
住所: K県F市

Re: for の条件

#4

投稿記事 by 沖 滉均 » 14年前

0.1などは2進数少数で循環小数になってしまい表示桁数を上げて表示してみると分かりますが
誤差が発生しているためですね。

「C言語 浮動小数点 誤差」辺りで検索してみると、より詳しい説明が見られると思います。

[追記]
他の作業しながらちんたら書いてたら、お二人が既に詳しく書かれていましたね^^;
There is no royal road to learning.
codeタグで指定できる言語
画像

アバター
GRAM
記事: 164
登録日時: 14年前
住所: 大阪

Re: for の条件

#5

投稿記事 by GRAM » 14年前

簡単に言うと普通の電卓で(関数電卓じゃない電卓で)1/3*3が1にならないのと似たような理由です

この手の誤差を回避するのに最も簡単な方法は
加算減算を整数で行うことです

コード:

#include <stdio.h>
 
int main(void)
{
    double f;
    for(f=1.0; f<100.0;f=f+1.0)
    printf("%f  ",f/10.0);
    
    return 0;
}
ほとんどすべての環境において
doubleが1刻みで精度を保障する範囲はint型のカバーする範囲よりも大きいので、大体の場合はこれでうまくいきます
よくある感じだとint型が2進数で31桁の整数があらわせますが、double型は53桁の整数まで正確に表せます
なので具体的には±9.0 × 1015位まで整数の加算減算の正確さが保障されます。

float使った場合、精度は極端に落ちて24桁くらいになることが多く
約1677万以上の整数は正確に扱えなくなりますので要注意です。

追記:少々間違いを訂正しました
最後に編集したユーザー GRAM on 2011年7月21日(木) 20:02 [ 編集 1 回目 ]

nao

Re: for の条件

#6

投稿記事 by nao » 14年前

なるほど!
やはり誤差が生じてしまうのですね・・・
実際に確認する方法も教えてくださってありがとうございます!!
これでまた独習を進められます
本当に答えてくださった皆様ありがとうございました!

nao

Re: for の条件

#7

投稿記事 by nao » 14年前

すいません
解決済みにしておきます!

閉鎖

“C言語何でも質問掲示板” へ戻る