N2
NanToo
開発者向け

IEEE 754 浮動小数点ビット分解 (binary16 / binary32 / binary64)

10 進数を IEEE 754 浮動小数点 (binary16 / binary32 / binary64) のビット列・16 進表現に分解し、 符号・指数・仮数の内訳と実際に表現される値・誤差を可視化するツール。 「0.1 + 0.2 が 0.3 にならない」 理由が一目で分かる。 16 進・ビット列からの逆引きも対応。

IEEE 754 浮動小数点ビット分解 (binary16 / binary32 / binary64)について

IEEE 754 浮動小数点ビット分解ツールとは

このツールは、 10 進数を IEEE 754 浮動小数点 (binary16 / binary32 / binary64) のビット列16 進表現に分解し、 符号・指数・仮数の内訳を色分けで可視化します。 逆に 16 進やビット列から 10 進値を復元することもできます。

0.1 + 0.2 = 0.30000000000000004」 のような浮動小数点の不思議な挙動は、 ビットを直接見ると一目で理解できます。 入力した 10 進値と、 floating-point で復元される値の絶対誤差も自動表示するので、 「この値は IEEE 754 で正確に表現できるか」 を即座に確認できます。

3 つの精度 ― half / single / double

IEEE 754 が定める主要な精度:

  • binary16 (half): 16 bit (符号 1 + 指数 5 + 仮数 10、 バイアス 15)。 GPU・機械学習推論・OpenEXR で多用。 最大 65,504、 精度 約 3.3 桁
  • binary32 (single, float): 32 bit (符号 1 + 指数 8 + 仮数 23、 バイアス 127)。 3D グラフィックス・組込みの定番。 精度 約 7.2 桁
  • binary64 (double): 64 bit (符号 1 + 指数 11 + 仮数 52、 バイアス 1023)。 JavaScript の Number、 Python の float、 C の double。 精度 約 15.9 桁

同じ「0.1」 でも精度が下がると誤差が大きくなり、 binary16 で 約 2.44×10⁻⁵、 binary32 で 約 1.49×10⁻⁹、 binary64 で 約 5.55×10⁻¹⁸ になります (本ツールで実測可能)。

「0.1 + 0.2 ≠ 0.3」 の正体

10 進で「有限」 な 0.1 は、 2 進では 0.000110011 0011 0011… と循環無限小数になります (1100 が永遠に繰り返す)。 これを binary64 の 52 ビット仮数に詰めるとき末尾を丸める必要があり、 ここで初期誤差が入ります。

0.3       hex = 3FD3333333333333
0.1 + 0.2 hex = 3FD3333333333334   ← 末尾 1 bit 違い

差は約 5.55×10⁻¹⁷。 「ほぼ等しい」 が「ビット単位で等しくはない」 ので === 比較は false を返します。 詳しい解説は 「0.1 + 0.2 が 0.3 にならない本当の理由」 記事へ。

実務での注意点

  • 等値比較: === は危険。 Math.abs(a - b) < εNumber.EPSILON 経由の許容比較を使う
  • 金額計算: 通貨は最小単位 (円・銭・cent) の整数で持つ。 Python なら decimal.Decimal
  • 大きな整数: 16 桁 (= 253-1 = 9,007,199,254,740,991) を超えると整数が連続表現できない。 JS なら BigInt、 JSON では文字列化
  • NaN: NaN === NaN は false (IEEE 754 仕様)。 Number.isNaN() を使う

よくある質問

Q. なぜ 0.1 + 0.2 が 0.3 にならない?
0.1 と 0.2 は 2 進では無限循環小数で、 IEEE 754 binary64 の 52 ビット仮数に詰めるとき末尾が丸められます。 この初期誤差が加算で残り、 0.3 とは末尾 1 ビットだけ異なる値 (差 約 5.55×10⁻¹⁷) になります。 言語のバグではなく、 ほぼ全ての現代コンピュータが採用する IEEE 754 規格の必然です。
Q. binary16 / binary32 / binary64 はどう使い分ける?
用途次第です。 JavaScript の Number / Python の float / C の double はすべて binary64 (倍精度、 約 15.9 桁) で、 ほとんどの場面ではこれで十分。 GPU シェーダーや組込みは binary32 (約 7.2 桁) でメモリと速度を稼ぐ。 機械学習推論や HDR レンダリングでは binary16 (約 3.3 桁) でさらに高速化。 精度を下げるほど誤差は大きくなります。
Q. 本ツールの計算は本物の IEEE 754 と完全一致?
完全一致します。 binary32 / binary64 は JavaScript の DataView 経由でブラウザ実装の IEEE 754 演算を直接使用、 binary16 は規格通りの round-to-nearest-even を自前実装しています (1.0 → 0x3C00, 0.1 → 0x2E66, 65504 → 0x7BFF など主要値を numpy half と突き合わせて検証済)。
Q. 16 進やビット列から復元できますか?
できます。 上部のモードを「16進」 または「ビット」 に切り替えて入力すると、 ビット列の意味分解と復元される 10 進値が表示されます。 「メモリダンプで見たこの 8 バイトは何の値?」 のような場面で便利です。
このツールを評価
(0件)