2012年6月27日水曜日

固定小数点演算信号処理の極意シリーズ (その4) 符号付き2進数

前回は、浮動小数点と固定小数点の話をしました.といっても、固定小数点の位取りの話までは達していないので固定小数点数値がどういうものなのかを理解できた人はまだいないと思います.今回は固定小数点数値の位取りの話と符号の話をするので、以下を読めば固定小数点数値の意味をわかっていただけると思います.

位取りとは、たとえば5bit binaryを、3+2bitに分けて、上位3bitを整数桁、下位2bitを小数桁とみなす、などと自分で決めることです.3+2bitに分けたときは、その表現可能範囲は下表のとおりになります.binaryは2進数です.decimalは10進数です.------位取りは設計者であるアナタの気持ち次第ですのでご注意のほど-------

3+2bitに分けたので、上位3bitで0~7の整数を表現できます.下位2bitの小数部は1を2bitで4分割するので0.25刻みの小数を表現できます.したがって、0~7.75の数値を表現できます.
binary    decimal
111.11    7.75
111.10    7.5
111.01    7.25
111.00    7.0
110.11    6.75
110.10    6.5
110.01    6.25
110.00    6.0
101.11    5.75
101.10    5.5
101.01    5.25
101.00    5.0
100.11    4.75
100.10    4.5
100.01    4.25
100.00    4.0
011.11    3.75
011.10    3.5
011.01    3.25
011.00    3.0
010.11    2.75
010.10    2.5
010.01    2.25
010.00    2.0
001.11    1.75
001.10    1.5
001.01    1.25
001.00    1.0
000.11    0.75
000.10    0.5
000.01    0.25
000.00    0.0

さてここからが本日の本題の符号付き2進数の話になります.負の数値をどうやって表現するんだい?っていう話です.

符号付き2進数の表現方法にはいろいろあるのですが、ここでは最も一般的に用いられている2の補数表現というのを解説します.一般的に用いられているの意味は、ADCやDACやFPGAの演算回路がこの2の補数表現で設計されているので、我々もそれに従うのがよいということです.もしも労を惜しまなければあなた独自の演算体系を作り上げても構いませんが相当かったるいでしょう.

まず、簡単な3bit binaryで2の補数表現をしてみます.要点は、
① MSB=0なら正の数値、MSB=1なら負の数値
② 数直線的に並べるには、MSB=0の数値を上に、MSB=1の数値を下に並び替える
③ 000ならゼロ
④ ゼロを中心に上下に絶対値を増やしてゆく
⑤ 正数は+3までなのに対し、負数が-4まである非対象さは我慢する   (あとでめんどくさいことになるんだこれが)
な~んか不思議な感じしかしませんが、でも2の補数とはこういうもんだ、と思ってもらうしかないです.桁数が増えても、小数を扱っても基本的な考え方は同じです.
binary   decimal
0 11       +3
0 10       +2
0 01       +1
0 00         0
1 11       -1
1 10       -2
1 01       -3
1 00       -4

次に、5bit binaryを、符号1bit+整数2bit+小数2bitに分割した符号付き固定小数点の表現可能範囲を下表に示してみます.青い正の範囲は上で描いたのと同じです.全然違うのは赤い負の範囲です.111.11が-0.25になってしまうんです.この変な感じは慣れで克服しましょう.結果的に、表現範囲は+3.75~-4.0となります.
binary    decimal
0 11.11    3.75
0 11.10    3.5
0 11.01    3.25
0 11.00    3.0
0 10.11    2.75
0 10.10    2.5
0 10.01    2.25
0 10.00    2.0
0 01.11    1.75
0 01.10    1.5
0 01.01    1.25
0 01.00    1.0
0 00.11    0.75
0 00.10    0.5
0 00.01    0.25
0 00.00    0.0
1 11.11    -0.25
1 11.10    -0.5
1 11.01    -0.75
1 11.00    -1.0
1 10.11    -1.25
1 10.10    -1.5
1 10.01    -1.75
1 10.00    -2.0
1 01.11    -2.25
1 01.10    -2.5
1 01.01    -2.75
1 01.00    -3.0
1 00.11    -3.25
1 00.10    -3.5
1 00.01    -3.75
1 00.00    -4.0

2の補数についての基本的なことは、だいたいこれで全部なのですが、便利なことを2つと、不便なことを2つ挙げておきます.

便利なこと1:
最初に示した3+2bit符号なしbinaryは、ADCのデータシートでよく見かけます.ADCの出力データ形式はたいていこの形式です.この形式をstraight binaryと呼称します.一方すぐ上の1+2+2bit符号付きbinaryは、2's complemetaryと呼称されます.2's complementaryのADCもたまにあります.
で、straight binaryを、2's complementaryに変換するのはとても簡単なんです.それは、 MSB を 符号反転するだけ でよいんです.このことは憶えておきましょう.

便利なこと2:
符号反転が簡単です.実際にやってみますと、
101.11    -2.25   これを符号反転してみます
各bitを反転します   010.00
LSBに1を足します     010.00 + 000.01 = 010.01
④ 010.01    2.25   そしたらあーら不思議、+2.25になりました

不便なこと1:
じつはこの符号反転には危険な罠があります.それは、マイナスの最小値を符号反転するとトラブることです.2の補数表現では+4.0が定義不可能なので、-4.0を符号反転しようとするとできません.そのことを示します.
① 100.00    -4.0    これを符号反転してみます
② 各bitを反転します   011.11
③ LSBを足します     011.11 + 000.01 = 100.00
④ 100.00    -4.0    そしたらあーら不思議、-4.0に戻ってしまいました.どひさん!!
これを見過ごしたfilterを設計してしまうと、飽和入力時にデータが化けて即死します.だから、100.00が入力されたら100.01に強制的に変換するという回路を追加して100.00を禁止しなくちゃいけません.このことは憶えておきましょう.

不便なこと2:
固定小数点演算回路では、N bit binaryにどういう位取りを持たせるかを設計者であるアナタの心の目で行わなくてはなりません.なので、ここの数値の位取りは何々だというのをコメントでいちいち記述しておかないとわけがわからなくなります.そのコメントの書き方について、ヒラサカが好きでやっている表記なんですが、こんな風に書いてはいかがでしょうか?
   (0.3.2)      符号なし5bit     整数3bit      小数2bit
   (1.2.2)      符号つき5bit     整数2bit      小数2bit
   (0.32.0)    符号なし32bit   整数32bit    小数0bit
   (1.15.16)  符号付き32bit   整数15bit    小数16bit
以後のこのシリーズでは、この表記で進めます.

蛇足とは思いますが、5bit binaryを(1.3.1)に位取りした場合の例を示しておきます.表現範囲は7.5~-8.0になります.
binary    decimal
0 111.1    7.5
0 111.0    7.0
0 110.1    6.5
0 110.0    6.0
0 101.1    5.5
0 101.0    5.0
0 100.1    4.5
0 100.0    4.0
0 011.1    3.5
0 011.0    3.0
0 010.1    2.5
0 010.0    2.0
0 001.1    1.5
0 001.0    1.0
0 000.1    0.5
0 000.0    0.0
1 111.1    -0.5
1 111.0    -1.0
1 110.1    -1.5
1 110.0    -2.0
1 101.1    -2.5
1 101.0    -3.0
1 100.1    -3.5
1 100.0    -4.0
1 011.1    -4.5
1 011.0    -5.0
1 010.1    -5.5
1 010.0    -6.0
1 001.1    -6.5
1 001.0    -7.0
1 000.1    -7.5
1 000.0    -8.0

次回はverilogについて少し学習します.             つぎへ            前へ
人気ブログランキングへ

0 件のコメント:

コメントを投稿