加算・乗算結果のビット幅
小数部がある符号付きの数(固定小数点)は次式で表せる。
固定小数点の数どうしの加減算・乗算結果は何ビット必要だろうか。なお以下では、固定小数点のビット幅を次のように書く。
<I.F>:整数部(integer part)がIビット、小数部(fractional part)がFビット |
◇
(1) 加減算
最下位ビットをそろえなければならないので小数部はビット数の大きい方になる。整数部は、最大でも2倍にしかならないので、大きい方のビット数より1ビット多ければよい。
<I1.F1> ± <I2.F2> = <I+1.F> ここでI=max(I1,I2), F=max(F1,F2) |
ただし<I+1.F>で表せる値のうち、端の値は使われない。
加算の場合、正の最大2I-1は使われない。
-2I = (-2I-1)+(-2I-1) ≦ <I.0> + <I.0> ≦ (2I-1-1)+(2I-1-1) = 2I-2
減算の場合、負の最小-2Iは使われない。
-2I+1 = (-2I-1)-(2I-1-1) ≦ <I.0> - <I.0> ≦ (2I-1-1)-(-2I-1) = 2I-1
◇◇
(2) 乗算
整数部、小数部とも元のビット数の和だけ必要である。
<I1.F1> * <I2.F2> = <I1+I2.F1+F2> |
ただし、整数部の最上位ビットは負の最小どうしをかけたときしか使われない。
正の最大は 負の最小*負の最小のとき |
<I.0> * <I.0> = <2I.0> (-2I-1) * (-2I-1) = +22I-2 |
例)I=8のとき h80 * h80 = h4000 |
正の2番目に大きい結果は 正の最大*正の最大のとき |
<I.0> * <I.0> = <2I-1.0> (2I-1-1) * (2I-1-1) = 22I-2-2I+1 |
h7F * h7F = h3F01 |
負の最小は 負の最小*正の最大のとき |
<I.0> * <I.0> = <2I-1.0> (-2I-1) * (2I-1-1) = -22I-2+2I-1 |
h7F * h80 = hC080 |
◇◇◇
(例) 5個の8ビットデータに12ビットの係数をかけて和をとるフィルタの出力ビット幅は?
8ビットデータと12ビット係数の乗算結果は8+12=20ビット。これを5個加算すると、「1回の加算で1ビット増えるから4回で4ビット増える」と考えるのは間違いで、5倍すると考えて5 < 23 だから3ビットだけ増やせばよい。結局、23ビットが正解。
◇◇◇◇
実用上は、実際に入力のとりうる値から演算結果のとりうる値の範囲を10進数で計算してみて、ビット幅を決めるのが簡単かもしれない。(→補足-10進数と2進数の桁数の関係)