パソコンで数値計算

オーバーフローとアンダーフロー

コンピューターは、非常に大きい値や小さい値は記憶できない

コンピューターは、無限の大きさを持つ値や、無限に小さい(限りなく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 更新