1/1 + 1/2 + 1/3 + ・・・ + 1/99999 + 1/100000 を計算するために、C言語で次の二つの関数 A、B を作った。ただし
float は IEEE754 に従う単精度 (32bit) の型であり、コンパイルされた機械語コードは、ソースコード中に記述された演算をすべて順序どおりに実行するものとする。
float A() {
int i; float sum = 0.0;
for (i=1; i<=100000; i++) {
sum += 1.0/(float)i;
}
return sum;
}
float B() {
int i; float sum = 0.0;
for (i=100000; i>=1; i--) {
sum += 1.0/(float)i;
}
return sum;
}
A、B の実行結果について、@〜Dの中から最も適切なものを選べ。
@ AとBの結果は同じ精度になる。
A Aの結果の方がBより精度が高い。
B Bの結果の方がAより精度が高い。
C Aはオーバフローになるが、Bは正常に実行できる。
D Bはオーバフローになるが、Aは正常に実行できる。
B
絶対値が大きい数と小さい数を足したり引いたりする場合に、その差が極端すぎて小さい方の値が無視されてしまう現象を情報落ちという。
Aのプログラムでは、1/1 + 1/2 + 1/3 + ・・・ と、大きい数字から足していくため、足しこんだ値に、さらに0.00001のような絶対値の小さい値を足しこんでも情報落ちして、精度が低くなる。
W−2 | 目次 | W−4 |