いきなりですが問題です.
「-3」という数を,マイナスの符号を使わず0と1だけで表すには,どうすればいいでしょうか.
さ
っ
そ
く
で
す
が
解
答
です.情報系の学部1年生には,次の3種類が思い浮かんでほしいと願っています.
- 符号ビットと絶対値で表す.
- 補数表現を用いる.
- "-3"を文字列として,1文字ずつ表してから連結する.
準備
「1ビット」あるいは単に「ビット」を,0か1の1文字(2進1桁)という意味とします.
2進数の複数の桁を一括して扱うときは,「nビット」と書きます.nには具体的な数(8など)が入ることもあります.
2進数の桁数を「ビット数」と呼びます.0000, 0001, 0010, ...は,いずれもビット数が4となります.ビット数が異なれば,値も異なるものとします.例えば,0と00と0000は異なる値です.
nビットあれば,種類の異なる状態を表現することができます.
符号ビットと絶対値
整数(正,負,0のいずれか)を,nビットで表現することにします.そのうち1ビットだけ「符号ビット」として扱います.マイナスの符号がつかないときは0,つくときは1とします.
残りn-1ビットで,数の絶対値を,2進数で普通に表現します.
「-3」だと,符号ビットは1,そして絶対値3の2進表現は11です.
nをいくつにするかは,そのあとで決めます.といってもn<3だとまずいので,n≧3とします.n=3だと,111です.n=8だと,10000011と書けます.左端の「1」が符号ビット,残りが絶対値です.
符号ビットと絶対値で表す場合,「0」と「-0」が別々の表現となります.n=3の場合,-3, -2, -1, -0, 0, 1, 2, 3の8種類を表現できます.
補数表現
補数表現を用いる場合,まずビット数を決めておきます.ここでは8とします.
もう一つ,決めごとがあります.2進数だと,「1の補数」と「2の補数」のどちらを選ぶかです.
1の補数は,各ビットの0,1を反転すれば出来上がりです.2の補数は,1の補数に1を加えたものとなります.いずれにせよ,-xは,xの「1または2の補数」*1によって表わされます.
10進数の-3については,まず符号を取り除いた3を8ビット(2進8桁)で表すと,00000011となります.
1の補数は,各ビットの0,1を反転すればいいので,11111100です.
2の補数は,そこに1を加えればいいので,11111101です.
補数は,検算ができます.xの「1の補数」の「1の補数」は,xです.xの「2の補数」の「2の補数」も,xです.
11111100の「1の補数」は,各ビットの0,1を反転すればいいので,00000011です.
11111101の「2の補数」を求めるため,まず「1の補数」を求めます.各ビットの0,1を反転すればいいので,00000010です.そして1を加えると,00000011です.
いずれも,00000011の「1または2の補数」の「1または2の補数」は,00000011となっています.
今回の例では,1を加える際に繰り上がりが見られませんでしたが,繰り上がりが発生する場合もあります.また,もとの数とその「2の補数」が同じとなるものもあります.00000000の「2の補数」は00000000,10000000*2の「2の補数」は10000000です.
計算機ではよく,2の補数表現が採用されます.これは,nビットならに着目した演算が効率良く行えるためです.先ほど-3は,2の補数によって11111101となると書きましたが,これを補数ではなく,普通に2進数とみなして,10進数に変換すると,253となります.
1を加えた11111110は254であるとともに-2です.さらに1を加えた11111111は255であるとともに-1です.もう一つ,1を加えると00000000(8ビットを前提とするので,最上位の繰り上がりを無視します)であるとともに0です.
このようになるのは,とが同一視されるからです.
文字列
文字列,あるいは文字の並びとして見るときは,文字コードを選ぶことから始めます.ここではASCIIを採用し,最上位ビットは常に0として8ビットで各文字を表すことにします.
"-3"だと,"-"のASCIIコードは00101101,"3"のASCIIコードは00110011,なのでくっつけて,00101101 00110011が,一つの表現となります.
他には,文字列には終端文字が含まれるとすることもできます.C言語はこの考え方です.終端文字には,どのビットも0の値,2進8桁で表すと00000000を採用します.そうすると,"-3"は00101101 00110011 00000000となります.
まとめ
- 符号ビットと絶対値:10000011
- 1の補数表現:11111100
- 2の補数表現:11111101
- 終端なしの文字列:00101101 00110011
- 終端ありの文字列:00101101 00110011 00000000
とはいえ,これですべてではありません.一つの固まりのビット長を変えれば,他の値になるわけですし,文字列についてはASCII以外の文字コード(例えばEBCDIC,UTF-16)を選べば結果は変わってきます.「バイアス」は,IEEE 754の指数部表現で使われています.
別名集
- 連結:concatenate,cat,連接
- に着目した演算:を法とする演算,mod
- 最上位ビット:MSB(most significant bitの頭文字)
- 終端文字:ナル文字,ヌル文字
- バイアス:エクセス,下駄を履かせる