1. はじめに(背景・目的)
float:浮動小数点数型は数値計算に広く使用される。
しかし、すべての数を正確に表現できるわけではない。
特に、1.0 にごく小さな値を加えた場合、その結果が変化せず 1.0 のままになる現象が発生する。
本記事では、次の問いを検証する。
float型ではどれだけ小さい値を加えると、加算結果が 1.0 のまま変化しなくなるか?
どれだけ小さい値なのか調べる!
2. 検証方法
2.1 使用環境
| 項目 | 内容 |
|---|---|
| 開発環境 | Microsoft Visual Studio Community 2019 |
| 言語 | C |
| 浮動小数点形式 | IEEE754 単精度(float, 32bit) |
2.2 検証内容
初期値:
af = 1.0fdeltaf = 0.1f
条件:
- 加算結果
af + deltafがafより大きい間だけ下記を実行する。
deltafを 1/2 に縮小**
# include <stdio.h>
int main(void){
float af = 1.0f;
float deltaf = 0.1f;
while (af + deltaf > af) {
deltaf /= 2;
}
printf("af = %f, deltaf = %f\n", af, deltaf);
}
このループでは、af + deltafがafより大きい間はdeltafを1/2に縮小し続ける。
条件af + deltaf > afが成り立たなくなった時点でループを抜け、そのときのdeltafを出力。
このときのdeltafが加算結果に影響を与えない最小の増分と考えられる。
3. 結果(失敗)
上記を踏まえ、プログラムを実行。結果を確認!!
af = 1.000000, deltaf = 0.000000
!!!
この結果では deltafの値が不明...
なぜ失敗したのか?
- 書式指定子
%fが小数点以下6桁までしか表示しないためだと考えられる。
4. 改善および結果
指数表記%eを用いて確認する。
簡易な修正のため、プログラムは割愛。
- 出力結果
af = 1.000000e+00
deltaf = 4.768372e-08
つまり、float型では 約 4.77×10⁻⁸ より小さい値を加えても 1.0 との差として認識されない ことが確認された。
5. 考察
上記の現象は数値計算における情報落ちの一例だと考えられる。
情報落ちとは、絶対値の大きく異なる二つの数を演算した際に小さい方の情報が失われてしまう現象を示す
6. 結論
float型ではどれだけ小さい値を加えると、加算結果が 1.0 のまま変化しなくなるか?
⇒4.768372e-08
浮動小数点は「厳密な数値」ではなく「近似表現」であることを理解して扱う必要がある。