- 2009-11-02 (月) 20:50
- blog
C/C++の話題。あんまり頭働いてない状態でコード書いてたら引っ掛かった!
なさけない話題なので書くの恥ずかしいんだけれど、教訓として残しておく。
int sum = 0;
for ( int i = 0; i < 10; i += 1 ) {
cout << i << ", ";
sum++;
}
cout << "num of loop execute: " << sum << endl;
たとえば上のようなコードだとループ内は10回実行されるのは当たり前なんだけれど、
下の場合はループ回数は不定となる(たぶん環境によりばらつきがある)。ぼくの環境では11回実行された。
int sum = 0;
for ( double i = 0.0; i < 1.0; i += 0.1 ) {
cout << i << ", ";
sum++;
}
cout << "num of loop execute: " << sum << endl;
他の例として、以下の例ではループが終了せず無限ループに入る。
ループ終了条件が != になってるだけです。
int sum = 0;
for ( double i = 0.0; i != 1.0; i += 0.1 ) {
cout << i << ", ";
sum++;
}
cout << "num of loop execute: " << sum << endl;
原因は、 11回目の実行時にdouble i が1.0であるにも関わらず i < 1.0 の終了条件を通ってしまうから。
3つ目の例での変数 i は、0.1ずつインクリメントしていっても(つまり0.0に10回0.1を足しても)厳密に「i == 1.0」にはならない可能性がある。
double, float等の浮動小数点は、完全に表現できない値がある。
たとえば0.1という数字は二進数にすると循環小数になり、そこで誤差が生じる。
まあ普通の計算では問題になりにくい程度の誤差だけれど、それをループ終了条件に用いた場合に誤差が効いてくる、ということ(だと思う)。
対策としてはループ終了条件を整数としてとれるように工夫する、ということくらいしか思いつかないのだけれど…
どこかで一度目にした教訓だったと思うのだけれど、実際に遭遇するとなかなか時間とられるなあ。
無限ループって怖くね?
ref: 無限ループ – Wikipedia
- Newer: 最近興味深かったページ(2009-11-05)
- Older: 休みがないでござる
コメント:0
トラックバック:0
- このエントリーのトラックバックURL
- http://www.masayashi.com/2009/11/02/1183/trackback
- Listed below are links to weblogs that reference
- ループの終了条件に小数を指定するのは避けるべき from 王様の箱庭