コンピューターは、無限の大きさを持つ値や、無限に小さい(限りなく0に近い)値はもちろんですが、非常に大きい値や、小さい値も記憶できません。その限度の値は、データ型の違いによって決まります。
オーバーフローやアンダーフローが発生すると、当然数値計算の結果にも影響します。数値計算の実行結果がおかしければ、オーバーフローやアンダーフローが発生している可能性があります。
オーバーフローとアンダーフロー
コンピューターは、非常に大きい値や小さい値は記憶できない
単精度浮動小数点変数のオーバーフローを調べる
以下は、単精度の浮動小数点変数にオーバーフローを発生させ、どのくらいの最大値まで表現できるのか調べるプログラムソースコード例です。
#include <stdio.h> int main(void) { int i; int N; float num = 1.0; printf("N = "); scanf("%d", &N); /* 2のN乗を計算し表示する */ for(i = 1 ; i <= N ; i++) { num *= 2.0; printf("%d %f\n", i, num); } return 0; }
数値計算実行結果
上記のプログラムをコンパイルし実行し、N の値を入力すると、以下のような結果が表示されます。
N = 128 1 2.000000 2 4.000000 3 8.000000 省略 126 85070591730234616000000000000000000000.000000 127 170141183460469230000000000000000000000.000000 128 1.#INF00ここでは、N を 128 としました。結果を見ると、2の128乗以上の値は表現できない事がわかります。ちなみに、1.#INF00 は、浮動小数点型変数がオーバーフローを起こしている事を意味しています。
単精度浮動小数点変数のアンダーフローを調べる
以下は、単精度の浮動小数点変数にアンダーフローを発生させ、どのくらいの最小値まで表現できるのか調べるプログラムソースコード例です。
#include <stdio.h> int main(void) { int i; int N; float num = 1.0; printf("N = "); scanf("%d", &N); /* 2の-N乗を計算し表示する */ for(i = 1 ; i <= N ; i++) { num /= 2.0; printf("%d %e\n", i, num); } return 0; }
数値計算実行結果
上記のプログラムをコンパイルし実行し、N の値を入力すると、以下のような結果が表示されます。
N = 150 1 5.000000e-001 2 2.500000e-001 3 1.250000e-001 省略 148 2.802597e-045 149 1.401298e-045 150 0.000000e+000
ここでは、N を 150 としました。
結果を見ると、2のー150乗未満の値は表現できない事がわかります。また、アンダーフローが発生すると、0になるという事もわかります。
2009/04/25 更新