IEEE754浮動小数点演算の効率化・除算

BASICMASTERchibiccCコンパイラ

chibiccー6800 の浮動小数点演算の効率化作業をしているんだけど、その過程でいくつかの知見を得た。たぶん、過去の文献や資料にある話だと思うのだけど、メモしておく。

ここでの対象は MC6800用のCコンパイラ chibicc用の浮動小数点ライブラリ。32bit floatを扱える。丸めは最近偶数丸めのみ。


IEEE754浮動小数点の実装

普段使ってるパソコンでは、浮動小数点演算はCPUがハードウェアで実行してくれるし、識者の作ったライブラリも揃っている。普通に使っている分には精度も速度も心配ない。

MC6800では そうはいかない。浮動小数点ハードウェアはない。それどころか整数の乗除算すらない。加減算は8bit単位だ。実に面倒臭い。

それでも、chibiccの移植を初めて2週間後には それっぽい浮動小数点ライブラリができていた。



このバージョンは 加減乗除と比較が動くだけのシロモノで、丸めも非正規化数もない。その頃の記事は以下にある。



実装には以下の書籍が参考になった。


IEEE754浮動小数点演算の丸め

さて、上記書籍にも書かれているが、丸めのためには仮数24bitを超える部分の情報が必要になる。

25,26bit目をGuard/Round bitと呼び、27bit目以降で1が立つビットがあればstick bitを立てる。この3bitと仮数の最下位ビット(L)を使って丸めを行う。

最近接偶数丸めだと round_up = G && (R || S || L); になる。

G R S 意味 L=0 L=1
0 0 0 正確 そのまま そのまま
0 0 1 1/4 ulp 未満 そのまま そのまま
0 1 0 1/4 ulp そのまま そのまま
0 1 1 1/4~1/2 ulp そのまま そのまま
1 0 0 ちょうど 1/2 ulp(tie) そのまま +1
1 0 1 1/2~3/4 ulp +1 +1
1 1 0 3/4 ulp +1 +1
1 1 1 3/4~1 ulp +1 +1


IEEE754浮動小数点除算の丸め

除算の場合は 少し計算を効率化できる部分がある。

除算は1回のループで1bitずつ求められるので、26bit計算して止める。このときの剰余が Sticky bit になる。剰余があれば S=1、なければ S=0 だ。
(剰余がStickyであることに気がつくまで5ヶ月かかっている)

最近、AIと議論してわかったのだが、実は除算の場合だけはもっと効率化できる。以下は2進数での除算が前提。
(非正規化数が絡むとややこしくなるので、正規化数の範囲で考える)

除算の結果は、循環する無限小数になるか割り切れるかのどちらかである。

割り切れる場合、被除数/除数を約分した分母は2の(べき)乗でないといけない。

2の冪乗であるということは、これは割算ではなく指数の調整だけで済む。ということは、除算後の仮数は24bit以下になる。したがって、S=0であればG=0,R=0である。


現れるパターンは 000 / 001 / 011 / 101 / 111 だけ。 G=0だと桁上げなしだし、G=1なら(Lに関わらず)桁上げが発生する。R/Sは見なくても良い。

使うのはGだけだが、商の最上位ビットが0になる場合は正規化で1bit喰われるので、26bit求めておく必要はある。

平方根も同様

仮数24bitを整数に見立てると、平方根の結果は整数になるか無理数である。整数ならS=0であり除算と同じ議論が成り立つ。

無理数の場合は1/2(有理数)になることはないので、G=1であれば切り上げて良い。

平方根では、丸めの結果で桁上がりして最上位ビットを超すことはないので、桁上げ後の補正もいらない。

資料

コメント

タイトルとURLをコピーしました