基本となる単精度浮動小数点演算
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進数ベースの浮動小数点フォーマットも追加されることになった。

この連載の記事
-
第852回
PC
Google最新TPU「Ironwood」は前世代比4.7倍の性能向上かつ160Wの低消費電力で圧倒的省エネを実現 -
第851回
PC
Instinct MI400/MI500登場でAI/HPC向けGPUはどう変わる? CoWoS-L採用の詳細も判明 AMD GPUロードマップ -
第850回
デジタル
Zen 6+Zen 6c、そしてZen 7へ! EPYCは256コアへ向かう AMD CPUロードマップ -
第849回
PC
d-MatrixのAIプロセッサーCorsairはNVIDIA GB200に匹敵する性能を600Wの消費電力で実現 -
第848回
PC
消えたTofinoの残響 Intel IPU E2200がつなぐイーサネットの未来 -
第847回
PC
国産プロセッサーのPEZY-SC4sが消費電力わずか212Wで高効率99.2%を記録! 次世代省電力チップの決定版に王手 -
第846回
PC
Eコア288基の次世代Xeon「Clearwater Forest」に見る効率設計の極意 インテル CPUロードマップ -
第845回
PC
最大256MB共有キャッシュ対応で大規模処理も快適! Cuzcoが実現する高性能・拡張自在なRISC-Vプロセッサーの秘密 -
第844回
PC
耐量子暗号対応でセキュリティ強化! IBMのPower11が叶えた高信頼性と高速AI推論 -
第843回
PC
NVIDIAとインテルの協業発表によりGB10のCPUをx86に置き換えた新世代AIチップが登場する? -
第842回
PC
双方向8Tbps伝送の次世代光インターコネクト! AyarLabsのTeraPHYがもたらす革新的光通信の詳細 - この連載の一覧へ











