整数の場合は、最下位のビットの重みは常に"1"であり、その上位は2、4、8というようになっていたが、浮動小数点の数値の場合は、ビットの重みが指数部によって変わる。従って、加算をする場合は、両者の数のEXP部の値の差を考慮して、桁あわせを行う必要がある。
図6:浮動小数点の加算をする場合は,EXPの差だけシフトして桁合わせを行う。 |
この図では、オペランド1のEXP1の方が大きいケースを示しているが、実際の演算では逆のケースもあり、その場合は、オペランド1を(EXP2-EXP1)ビット右シフトして桁をあわせる。これを実行する回路は、次の図7のようになる。
図7:浮動小数点 加算回路の桁あわせと加算部分 |
まず、比較回路で、EXP1とEXP2の大小を比較し、EXP2の方が大きい場合は入れ替えスイッチを切り替え、Frac1を右シフタに入れる。なお、図には明示されていないが、入れ替えスイッチを出るところでは、Hidden Bitが補われているものとする。
桁合わせのためのシフト数は、EXP1-EXP2であるので、これを引き算器(SUB)で計算し、右シフタに入力する。これで桁が揃ったので、アダー(ADD)に入れて和を求める。このアダーの幅であるが、オペランドのサイズは53ビットであるが、ガードビットとラウンドビットを計算する必要があり、55ビットの幅が必要である。また、また、右シフトされたオペランドの、それより下位の桁に"1"のビットがあったかどうかを記憶するスティッキービットを求めて出力する必要がある。
図7の回路では符号の取り扱いが省略されているが、両方のオペランドの符号が同じ場合は、アダーは加算を行えば良いが、符号が異なる場合には、引き算をする必要がある。また、この回路で処理できるのは、両方のオペランドが正規化された数の場合だけであり、IEEE 754規格に適合するためには、入力オペランドがデノーマル数やNaNでないことを確認する回路を設けて、これらの処理できない入力の場合は、トラップをあげて、ソフトウェアに処理を依頼する必要がある。
加算結果のノーマライズ
加算はこれで終わりではない。結果の数値をIEEE754の正規の数になるように、正規化するという作業が必要である。
図8:和に桁上りが生じた場合は、結果のEXPは大きいほうのオペランドのEXPに+1し、数値は1ビット右シフトして、正規化する必要がある。 |
図8のように、アダーで加算を行うと、値がオーバーフローしてキャリーが出る場合がある。この例では、オペランド1が29.1875で、オペランド2が3.140625で、合計は32を超える。従って、結果のEXPは1027ではなく、1028にする必要がある。なお、結果の灰色で塗られたマスの"1"はHidden Bitとなるので、結果としては格納されないが、ここでは、分かり易いように書き加えてある。
次の図9は、双方のオペランドの符号が異なっており、アダーが引き算を行う場合である。
図9:オペランドの符号が異なり、引き算になる場合。図7とは逆に最上位ビットがゼロになる場合がある。 |
この場合は、図8の場合とは逆に、最上位ビットがゼロになる場合がある。そして、結果は1ビット左シフトされて、結果のEXPの値は、入力オペランドの大きいほうのEXP値からマイナス1される。左に1ビットシフトすると、ガードビットが結果の最下位のビットとなるので、この場合でも精度は失われない。また、ラウンドビットとその下のスティッキービットが残っているので、丸めも正確に行うことができる。