実は、オペランド1とオペランド2の値がほぼ同じで、符号が違っており、アダーで引き算が行われる場合は、もっと厄介である。

図10:オペランド1が正、オペランド2が負で、値がほぼ等しい場合は、桁落ちが生じて差の多くの上位ビットがゼロになる。

図10に示すように、オペランド1と2の値がほぼ等しく符号が異なる場合は、差をとると、上位のビットはゼロが続くことになる。図中の矢印のように、この場合でも、最上位の"1"がHidden Bitの位置にくるように左シフトを行い、それに合わせて結果のEXPを調整する必要がある。

差の値を1ビットづつ左シフトし、結果のEXPの値を1づつ引くという操作を、最上位ビットが"1"になるまで繰り返せば良いのであるが、これではノーマライズに時間がかかってしまう。このため、最近のマイクロプロセサでは、上位のゼロが何個続いているかを数えるリーディングゼロカウンタと左シフタを備え、1サイクルでノーマライズを実現している。

図11:リーディングゼロカウンタの前段の回路。紙面の制約で、この図は16ビット分であるが、実際にはオペランドのビット数分の長さが必要。

リーディングゼロカウンタは、まず、図11のように、D15とD14がゼロの連続という信号Z15-14 などの2ビットのペアのゼロの連続信号を作り、次に、それらのペアからZ15-12のように4ビットのゼロ連続信号を作るというように倍々のビット数のゼロ連続信号を作る。

そして、Z15-0が"1"の場合は全部のビットがゼロであるので、16ビットシフト。Z15-0が"0"で、Z15-8が"1"の場合は、少なくとも、8ビットシフトが必要。という風に考えていくと、2進で表わしたシフトカウントは次のようになる。(なお、次の論理式で、* は否定を表わす)

  • 16ビットシフト:Z15-0
  • 8ビットシフト:*Z15-0・Z15-8
  • 4ビットシフト:*Z15-0・(*Z15-8・Z15-12+Z15-8・*Z7-0・Z7-4)
  • 2ビットシフト:*Z15-0・(*Z15-8・(*Z15-12・Z15-14+Z15-12?・Z11-8・Z11-10)+Z15-8・*Z7-0・(*Z7-4・Z7-6+Z7-4・*Z3-0・Z3-2))
  • 1ビットシフト:*Z15-0・(*Z15-8・(*Z15-12・(*Z15-14・D14+Z15-14・*Z13-12・D12)+Z15-12・*Z11-8・(*Z11-10・D10+Z11-10・*Z9-8・D8))+Z15-8・*Z7-0・(*Z7-4・(*Z7-6・D6+Z7-6・*Z5-4・D4)+Z7-4・*Z3-0・(*Z3-2・D2+Z3-2・*Z1-0・D0)))

これが、リーディングゼロカウンタの後段の論理となる。そして、このコラムの割り算器シリーズの最後に書いた2進N段のシフタの各段のスイッチの制御信号に接続すると、次の図のようにノーマライズ回路が出来上がる。

図12:リーディングゼロカウンタとシフタを組み合わせたノーマライズ回路。

リーディングゼロカウンタの後段の論理を見ると、シフト数が多い制御信号の方が生成論理が簡単であるので、遅延時間の観点から、シフタはシフトするポジションの多い順に前に置き、一番論理の複雑な1ポジションシフトのスイッチを最後に置いている。

なお、この例のように16ビット入力の場合は、最大15ビットのシフトを行えば良いので、16ポジション左シフトのスイッチは不要であるが、本物の浮動小数点加算器ではもっと長いビット数のノーマライズが必要であるので、拡張の考え方を示す意味で記述している。

また、加算結果の符号は、オペランドのEXP値に差がある場合はEXP値の大きい方のオペランドの符号となるが、EXP値が等しい場合は、第1オペランドから第2オペランドを引くと結果が負になる場合がある。この場合は、加算結果を2の補数に変換し、第1オペランドの符号を反転して結果の符号とする必要がある。

丸め

前に述べたように、IEEE754ではNearest(最近似値)以外に、切り上げ、切捨て、正、負の∞方向への丸めが規定されており、指定された丸めモードに従って、丸め処理を行う必要がある。

もっとも近い値に丸めるNearestは、無限精度での計算結果と一番近い、表現可能な数に丸めると規定されている。また、表現可能な2つの数のちょうど真ん中になった場合は、最下位ビットがゼロになる方に丸めると規定されており、正確には、四捨五入とは異なる。これを図示すると、次の図13のようになる。

図13:Nearestは、等距離の場合は最下位ビットがゼロになる方に丸める。この例では0.5LSB小さい数になり、四捨五入とは異なる。

ちょうど真ん中の場合は、表現可能などちらの数にしても誤差は同じであるが、このように、最下位ビットがゼロになるように丸めるのは、数値を表現するのに必要なビット数を減らす方向に丸める方が、この後の計算の精度の点で有利だからである。

ハードウェア設計の観点から言うと、LSBの次のビットの"1/0"だけで判定できる四捨五入の方が簡単であるが、このように、IEEE754規格では出来るだけ精度を確保するように、細かい配慮が行われている。

図13の例では、0.5LSB小さい数に丸められるのでLSB以上の上位ビットには影響が無いが、次の図のように、0.5LSB大きい数に丸められ、さらに、LSBやその上のビットが"1"の場合には、影響が出てくる。

図14:丸めの影響が上位のビットに及ぶケース。

この図14の例では、丸めのために、LSBから上位方向に3ビットが変化しているだけであるが、LSBから上位のビットが全て"1"というケースでは、丸めのために、オーバーフローが生じることになる。このような場合には、結果を1ビット右シフトして、EXP値を+1するという処理が必要になる。