【ふどうしょうすうてん】

浮動小数点 とは?

💡 コンピュータが実数を表現する仕組み、「0.1+0.2が0.3にならない」の原因
📌 このページのポイント
浮動小数点数(IEEE 754 単精度:32ビット) ビット構成 符号 1ビット 指数部(エクスポーネント) 8ビット 仮数部(マンティッサ) 23ビット 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 ... 0 計算式: (-1)^符号 × 1.仮数部 × 2^(指数部-127) 例: 0 10000000 10010010... = +1.5707... × 2^1 ≈ 3.14159... メリット 非常に大きい数〜非常に小さい数を 限られたビットで表現できる 注意点 0.1 + 0.2 ≠ 0.3 のような 丸め誤差が発生する場合がある 小数点の位置を「浮動」させて広い範囲の数値を表現する方式
浮動小数点数のイメージ
ひよこ ひよこ

浮動小数点って何?

ペンギン先生 ペンギン先生

コンピュータが実数(小数を含む数)を表現する方法。例えば「1.23×10²」のように「仮数(1.23)× 基数(10)の指数(2)乗」の形で数を表す。非常に大きな数(宇宙の星の数)や小さな数(原子の質量)まで表現できる。

ひよこ ひよこ

0.1+0.2が0.3にならないのはなぜ?

ペンギン先生 ペンギン先生

コンピュータは2進数で数を表現するため。10進数の0.1は2進数では0.000110011…と循環小数になって正確に表せない。だから0.1と0.2を足すと微妙な誤差が累積して0.30000000000000004になる。どの言語でも同じ問題が起きる(IEEE 754規格のため)。

ひよこ ひよこ

お金の計算はどうするの?

ペンギン先生 ペンギン先生

金額計算にfloatやdoubleを使ってはいけない。1円の誤差が命取り。代わりにDecimal型(10進数で正確に表せる固定小数点数)を使う。JavaはBigDecimal、PythonはDecimalモジュールJavaScriptなら整数(銭単位)で計算するなどの対策が必要。

ひよこ ひよこ

浮動小数点の誤差でバグが起きた有名な事例ってあるの?

ペンギン先生 ペンギン先生

1991年の湾岸戦争でパトリオットミサイルの時刻計算に浮動小数点誤差が蓄積し、0.34秒のズレが生じてスカッドミサイルの迎撃に失敗、28人が死亡した事故が有名だよ。0.1秒を2進数で正確に表せないことが原因だったんだ。

ひよこ ひよこ

NaN(Not a Number)って何なの?

ペンギン先生 ペンギン先生

「数値として表現できない結果」を表す特殊な値。0÷0やMath.sqrt(-1)の結果がNaN。面白いのはNaN === NaN がfalseになること。自分自身と等しくない唯一の値だよ。NaNのチェックにはisNaN()やNumber.isNaN()を使う。浮動小数点の仕様(IEEE 754)で明確に定義されている特殊値なんだ。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
浮動小数点って出てきたら「コンピュータの実数表現方式、2進数の誤差でほぼ全言語で0.1+0.2≠0.3になる」と思えばOK!
📖 おまけ:英語の意味
「Floating Point」 = 浮動小数点(小数点が浮いて移動する)
💬 固定小数点(Fixed Point)に対して「小数点の位置が仮数と指数で動く(浮く)」ことから命名。1985年にIEEE 754として標準化されたことで現代コンピュータの実数表現の標準となった
← 用語集にもどる