基本となる単精度浮動小数点演算
2進数を10進数に変換すると誤差が生まれる
まず基本であるBinary32の説明をしよう。いわゆる単精度浮動小数点演算と呼ばれているものに使われるのがこれだ。この内部フォーマットは下図のようになっている。
「あれ、上の表と仮数のサイズが違う」といわれそうだが、上の表は仮数部に符号bitを含んだものになっている。つまり符号+23bitで合計24bitという表現である。
さて、符号bitは0なら正、1なら負でこれはダイレクトだが、その先はやや複雑な仕組みである。まず指数部。00000000(0)の場合は数字そのものが0、もしくは非正規数(0ではないけど、限りなく0に近い小さな数字)を、11111111(255)の場合は無限大もしくはNaN(Not a Number:数字ではない)を意味する。
普通の数字なら00000001(1)~11111110(254)までの範囲になるのだが、ここから127を引いて-126~127の値を表現する。つまり2-126~2127という範囲になる。
一方仮数部。こちらは指数部が0でない場合、最上位に暗黙の“1”を立てる。すると仮数部は23bit分しかないにもかかわらず、実質的に24bit分になる。
これが大きいのは、23bitでは10進相当で6.923桁分で、つまり有効数字が7桁にならない。ところが24bitにすると7.224桁分で、有効数字が7桁になるためである。よって仮数部の表現は頭に1がついており、これが"1."に相当する。下の例がわかりやすいだろう。
Binary32での演算 | ||||||
---|---|---|---|---|---|---|
仮数部の表現 | 内部での扱い方 | 値 | ||||
00000000000000000000000 10000000000000000000000 11000000000000000000000 11100000000000000000000 : 11111111111111111111111 |
100000000000000000000000 110000000000000000000000 111000000000000000000000 111100000000000000000000 : 111111111111111111111111 |
1.0 1.5 1.75 1.875 : 1.99999988079071 |
この「値」は2進数なので、1.0~1.999999...の範囲に収まる形になる。もちろんこれは内部表現であって、実際には10進数に内部で変換して出力することになる。
Binary64/128/256は、単純に仮数部と指数部の桁が増える(結果、仮数部の有効数字が増え、また扱える値の範囲が広がる)し、逆にBinary16は桁が半分以下に落ちるので、有効数字・扱える値の範囲ともに狭まることになる。
ちなみにDecimal32/64/128は、きちんと10進数の演算が必要な場合に利用される。Decimal32では以下のようになり、きちんと割り切れる数字ではない。
Decimal32での演算 | ||||||
---|---|---|---|---|---|---|
仮数部の表現 | 内部での扱い方 | |||||
00000000000000000000000 01000000000000000000000 00100000000000000000000 00010000000000000000000 00001000000000000000000 00000100000000000000000 00000010000000000000000 00000001000000000000000 00000000100000000000000 00000000010000000000000 00000000001000000000000 00000000000100000000000 00000000000010000000000 00000000000001000000000 00000000000000100000000 00000000000000010000000 00000000000000001000000 00000000000000000100000 00000000000000000010000 00000000000000000001000 00000000000000000000100 00000000000000000000010 00000000000000000000001 |
1.5 1.25 1.125 1.0625 1.03125 1.015625 1.0078125 1.00390625 1.001953125 1.0009765625 1.00048828125 1.000244140625 1.0001220703125 1.00006103515625 1.000030517578125 1.0000152587890625 1.00000762939453125 1.000003814697265125 1.0000019073486325625 1.00000095367431628125 1.000000476837153140625 1.0000002384185765703125 1.00000011920928828516625 |
10進法なら1.1+0.1=1.2は当たり前だが、2進法ではこれが「1.1に限りなく近い値」+「0.1に限りなく近い値」という計算になるため、たまに1.2にならない場合がありえる(有効数字次第ではあるが)。
実はこれにまつわる有名な話がある。米軍のパトリオット地対空ミサイルが、湾岸戦争のさなかの1991年2月、イラク軍のスカッドミサイルの迎撃に失敗するという事件があった。
この原因は、パトリオットの制御に利用していたプログラムが、内部で24bitのカウンターを利用して時間を測定していたのだが、2進/10進の変換の誤差が蓄積した結果、タイミングが0.34秒ずれたことである。
原因がわかったことで、現場での対処(煩雑にシステムを再起動して誤差の蓄積を解消)が可能になったが、根本的には2進数をベースにするとどうしても誤差を避けられないということで、こうした用途向けに10進数ベースの浮動小数点フォーマットも追加されることになった。

この連載の記事
-
第817回
PC
実現困難と思われていたUCIe互換のチップレット間インターコネクトをTSMCとAMDが共同で発表 ISSCC 2025詳報 -
第816回
PC
シリコンインターポーザーを使わない限界の信号速度にチャレンジしたIBMのTelum II ISSCC 2025詳報 -
第815回
デジタル
3次キャッシュがスリムになっていたZen 5、ISSCCで公開された詳報 AMD CPUロードマップ -
第814回
PC
インテルがチップレット接続の標準化を画策、小さなチップレットを多数つなげて性能向上を目指す インテル CPUロードマップ -
第813回
PC
Granite Rapid-DことXeon 6 SoCを12製品発表、HCCとXCCの2種類が存在する インテル CPUロードマップ -
第812回
PC
2倍の帯域をほぼ同等の電力で実現するTSMCのHPC向け次世代SoIC IEDM 2024レポート -
第811回
PC
Panther Lakeを2025年後半、Nova Lakeを2026年に投入 インテル CPUロードマップ -
第810回
PC
2nmプロセスのN2がTSMCで今年量産開始 IEDM 2024レポート -
第809回
PC
銅配線をルテニウム配線に変えると抵抗を25%削減できる IEDM 2024レポート -
第808回
PC
酸化ハフニウム(HfO2)でフィンをカバーすると性能が改善、TMD半導体の実現に近づく IEDM 2024レポート -
第807回
PC
Core Ultra 200H/U/Sをあえて組み込み向けに投入するのはあの強敵に対抗するため インテル CPUロードマップ - この連載の一覧へ