前回に浮動小数点演算について説明したのは除算のためでした。
実数でないといろいろ問題があるんで
SPUには除算命令ってのがありません。
そのため、複数の命令を使って除算を実現します。
後、浮動小数点を即値でロードする際ですが、0.5とか1.0とか入力しても駄目です。
(何かやる方法があればなぁと思い調査中)
通常(コンパイラ)は、浮動小数点で表した数値と同じbit配置の数値で入力しています。
これも、前もって説明しておけばよかったと反省。
今回は、そんな細かいことは無視して実数をそのまま入力するようにします。
その方が分かりやすいので。
除算プログラムですが、
一度簡単なプログラムを見せてから説明したほうが早いと思うので、
とりあえず見てください。
a = 1.0
b = 0.4
c = a / b を考えます。
il $5 1.0
il $6. 0.4
frest $7,$6
fi $7,$6,$7
fm $8,$5,$7
ってな感じで、答えは$8に入ります。
ilってのは単にロードで、
今回は、レジスタ5に1.0を、レジスタ6に0.4をロードしました。
frestですが、これは0.4の逆数を求めています。
つまり、1/0.4です。
しかし、この計算では若干精度が悪いといった問題があります。
そこでfiという命令を使って
より精度の高い逆数を求めます。
$6には元々の実数の値を、$7にはfrestで求めた逆数を入力します。
逆数を求めた結果が$7に格納されます。
fmは前回にも説明した
浮動小数点の乗算命令です。
要は
c = a * (1/b)
を計算しているんですね。
なんで、除算をするのにこんなことをしているのか
これはちょっと、自分も自身はないのですが、
コンピュータには割り算命令がないってのは、最初に説明しましたが
(全部がそうとは限らない(?)自分も分からないのですがPentium 4にもないと聞きました。)
そのため、逆数を求めるテーブルってのがありまして、
そこから逆数の値を求めます。
でもそれだと精度が悪いため、
ニュートンラプソン法を使って、より精度の高い値に収束させます。
恐らく一回しか、計算してないようですが・・・
元々、それなりの値を初期値を入力しているので
1回でも、精度の高い値に収束するみたいです。
このように、精度の高い逆数を求めるのが、fi命令だと思われます。
これを複数回行えばより精度の高い値も出せそうですが
1回でも十分な結果は得られます。
PR