IEEE 754 浮動小数点ビット表現
入力
| 精度 | 単精度(32ビット) |
|---|---|
| 10進数 | 3.14 |
IEEE 754 浮動小数点ビット表現
10進数を IEEE 754 の符号部・指数部・仮数部・16進数表現に分解します。単精度と倍精度を切り替えて丸め誤差を確認できます。
入力
数値
結果
値を入力すると計算結果が表示されます。
ビットレイアウト
格納値
IEEE 754 浮動小数点ビット表現
コンピュータが扱う実数のほとんどは、IEEE 754 規格に従った浮動小数点数として格納されています。IEEE 754 は 1985 年に米国電気電子学会(IEEE)が制定し、2008 年に改訂された国際標準規格で、現代のプロセッサとプログラミング言語のほぼすべてがこの規格に準拠しています。
ビットレイアウト
IEEE 754 では、1つの浮動小数点数を 符号部・指数部・仮数部 の3つのフィールドに分割して格納します。
単精度(32ビット)のフィールド構成は次のとおりです。
| フィールド | ビット位置 | ビット幅 |
|---|---|---|
| 符号部 | 31 | 1 |
| 指数部 | 30〜23 | 8 |
| 仮数部 | 22〜0 | 23 |
倍精度(64ビット)では指数部が 11 ビット、仮数部が 52 ビットに拡張され、符号部は同じく 1 ビットです。
正規化数の値は次の式で復元されます。
(−1)S×1.M×2E−biasは符号ビット、 は格納された仮数の小数部分(2進数として解釈)、bias は単精度で 127、倍精度で 1023 です。 の先頭の 1 は暗黙的に省略されており、ビット列には格納されません。この「隠れた 1 ビット」によって、仮数部は 1 ビット分の精度を追加で確保しています。
なぜ 0.1 は正確に格納されないのか
10進数の分数のうち、2進数で有限桁に終わるものは、分母の素因数が 2 だけで構成されるもの(1/2、1/4、1/8 など)に限られます。0.1 = 1/10 の場合、10 の素因数は 2 と 5 であるため、2進数では循環小数になります。
0.110=0.0001100110011…2仮数部のビット幅は有限(単精度 23 ビット、倍精度 52 ビット)なので、この循環するビット列は最近傍の表現可能な値に丸められます。倍精度での格納値は約 0.10000000000000000555 であり、厳密な 0.1 とは異なります。
この丸め誤差は単独では無視できる大きさですが、演算を重ねると累積します。
0.1+0.2=0.30000000000000004これは実装のバグではなく、2進数表現の必然的な帰結です。「格納値」欄には格納されたビットパターンの正確な10進数の値が表示されるので、任意の数値で丸め誤差を確認できます。
特殊値
IEEE 754 は特定のビットパターンを特殊値として予約しています。
| 指数部のビット列 | 仮数部 | 意味 |
|---|---|---|
| 全ビットが 0 | 全ゼロ | ±0 |
| 全ビットが 0 | 非ゼロ | 非正規化数(極めて小さい値) |
| 全ビットが 1(255/2047) | 全ゼロ | ±無限大 |
| 全ビットが 1(255/2047) | 非ゼロ | NaN(非数) |
非正規化数(サブノーマル数)は先頭の暗黙的な 1 ビットを放棄することで、最小の正規化数よりもさらに小さい値を表現します。その代償として精度が低下します。無限大はオーバーフローやゼロ除算で発生し、NaN は 0 ÷ 0 や √−1 のような未定義の演算から生じます。
単精度と倍精度の比較
| 項目 | 単精度(32ビット) | 倍精度(64ビット) |
|---|---|---|
| 符号部 | 1 ビット | 1 ビット |
| 指数部 | 8 ビット(バイアス 127) | 11 ビット(バイアス 1023) |
| 仮数部 | 23 ビット | 52 ビット |
| 有効桁数 | 約 7 桁 | 約 15〜17 桁 |
| 表現範囲(絶対値) | 約 1.2 × 10⁻³⁸ 〜 3.4 × 10³⁸ | 約 2.2 × 10⁻³⁰⁸ 〜 1.8 × 10³⁰⁸ |
C 言語の float、Java の float は単精度に、double は倍精度に対応します。Python の float は内部的に倍精度です。
単精度が好まれる用途は、グラフィックス処理(GPU のシェーダ)、ニューラルネットワークの重みパラメータ、組み込みファームウェアなど、メモリ帯域幅や処理速度が演算精度より優先される場面です。一般的な科学技術計算や金融計算では倍精度が標準的な選択肢です。
16進数表現の読み方
16進数フィールドはビットパターン全体を簡潔に表したもので、16進数 1 桁が 4 ビットに対応します。単精度は 8 桁、倍精度は 16 桁です。
エンジニアがビット列を16進数で扱うのは、無限大や NaN などの特殊パターンの識別、プラットフォーム間でビットパターンを完全に保持したシリアライズのデバッグ、浮動小数点値のビットレベルでの比較などの用途があるためです。
たとえば、円周率 π を単精度で格納すると 0x40490FDB、倍精度では 0x400921FB54442D18 になります。倍精度の仮数部に多くのビットが割り当てられていることが16進数からも確認できます。2進数や16進数の変換については、基数変換ツールも参照してください。
よくある質問 (FAQ)
0.1 が正確に格納されないのはなぜですか
IEEE 754 は数値を2進数で格納しますが、10進数の 0.1 は2進数では循環小数になります。これは、1/3 が10進数で 0.333… と終わらないのと同じ原理です。仮数部のビット幅には限りがあるため(単精度 23 ビット、倍精度 52 ビット)、最も近い表現可能な値に丸めて格納されます。倍精度の場合、格納される値は約 0.10000000000000000555 です。この丸め誤差が積み重なるため、0.1 + 0.2 の演算結果は 0.3 ではなく 0.30000000000000004 になります。「格納値」欄には格納されたビットパターンの正確な10進数値が表示されるので、任意の数値で丸め誤差を確認できます。
単精度と倍精度はどのように使い分けますか
倍精度(64ビット)は有効桁数が 15〜17 桁あり、多くのプログラミング言語で浮動小数点型の既定値として採用されています。単精度(32ビット)は有効桁数が約 7 桁と少ないものの、メモリ消費が半分で、32ビット浮動小数点演算専用のハードウェアでは処理速度も向上します。グラフィックス処理・機械学習の重みパラメータ・組み込みシステムなど、演算精度よりもメモリ帯域幅や処理速度が優先される用途では単精度が広く使われています。