符号付数値表現
符号付数値表現(ふごうつきすうちひょうげん)とは、コンピュータ内部での数値の正負(ゼロより大きいか小さいか)の表現方法である。
数学では、負の数はどういう場合でも一般的にマイナス記号「−」を数値の前に付けることによって表すことができる。しかし、コンピュータにとっては負の数を表す方法は一種類ではない。ここでは、二進記数法を拡張して負の数を表す方法を四種類説明する(符号-仮数部、1の補数、2の補数、エクセスN)。
ほとんどの場合、最近のコンピュータでは2の補数表現を使うが、他の表現が全く使われないわけではない。
符号-仮数部
ビットパターン | 符号-仮数部表現 | 符号無し表現 |
---|---|---|
00000000 | 0 | 0 |
00000001 | 1 | 1 |
... | ... | ... |
01111111 | 127 | 127 |
10000000 | −0 | 128 |
... | ... | ... |
11111111 | −127 | 255 |
二進数に符号をつける問題を考えたときに最初に思いつくのが、符号ビットを追加して正負を表すことである。つまり符号ビット(一般に最上位ビット(MSB)を割り当てる)が0ならば正の数を示し、1ならば負の数を示す。他のビット列はその数値の仮数部(あるいは絶対値)となる。1バイトで数値を表す場合符号に1ビットを使うので、7ビットで表せる仮数部は 0000000 (0) から 1111111 (127) となる。したがって、1バイトで表せる数値は−12710 から +12710 となる。結果として、この表現方法では 0 の表現が二種類できてしまう(00000000 (0) と 10000000 (−0))。十進数の −43 はこの方式では 10101011 と表現される。
この手法は(数字列の前に "+" や "−" を付与する)通常の符号の表し方そのままと言える。初期の二進コンピュータ(例えばIBM 7090)はこの表現方法を採用していたものもある。おそらく一般的な表現手法からの自然な連想によるものと思われる。また、多くの十進コンピュータは 符号-仮数部 を使っている。
1の補数
ビットパターン | 1の補数表現 | 符号無し表現 |
---|---|---|
00000000 | 0 | 0 |
00000001 | 1 | 1 |
... | ... | ... |
01111101 | 125 | 125 |
01111110 | 126 | 126 |
01111111 | 127 | 127 |
10000000 | −127 | 128 |
10000001 | −126 | 129 |
10000010 | −125 | 130 |
... | ... | ... |
11111110 | −1 | 254 |
11111111 | −0 | 255 |
二進数における1の補数表現は、負の数の表現に絶対値のビット単位のNOTを適用することで得られる。符号-仮数部 表現のように、1の補数でも 0 には二種類の表現がある(00000000 (+0), 11111111 (−0))。
例えば、00101011 (43) の1の補数は、11010100 (−43) である。1バイト幅で1の補数で表せる数値の範囲は −12710 から +12710 となる。
この体系でふたつの数の足し算をするには、まず通常の二進数の加算を行い、演算の結果出てきたキャリー(桁あふれ)を戻して加算する必要がある。なぜそうなるのかを知るために、−1 (11111110) と +2 (00000010) を加算してみよう。二進数の加算を行うと 00000000 となってしまい、正しい答えではない。これにあふれた桁(キャリー)を加算すると正しい答え (00000001)が出てくるのである。
この数値表現体系は古いコンピュータでは一般的だった。PDP-1とかUNIVAC 1100/2200 seriesなど多くのシステムが1の補数を使っていた。
なお、「1の補数」表現とは、英語では "ones' complement" であり、「2の補数」が "two's complement" と表記されるのとはアポストロフィーの位置が異なる。これは、1の補数が実際には 1 がずらっと並んだものから元の数を引くことで符号を反転させるためである。2の補数では単一の2のべき乗から元の数を引いて符号を反転させる。[1]
指数-仮数部表現で負数の仮数部をビット毎に反転させると、1の補数表現に変換される。
2の補数
ビットパターン | 2の補数表現 | 符号無し表現 |
---|---|---|
00000000 | 0 | 0 |
00000001 | 1 | 1 |
... | ... | ... |
01111110 | 126 | 126 |
01111111 | 127 | 127 |
10000000 | −128 | 128 |
10000001 | −127 | 129 |
10000010 | −126 | 130 |
... | ... | ... |
11111110 | −2 | 254 |
11111111 | −1 | 255 |
0が二種類の表現を持つという問題、キャリーを戻して加算しなければならない問題は、2の補数という体系を使うことで回避できる。2の補数では、負の数は(符号なしの感覚で言うと)1の補数より1だけ大きいビットパターンで表される。
例えば、8ビットの整数では値は右表のようになる。 2の補数では、ゼロ(00000000)は一種類しかない。数値の逆数を得るには(元の数値が正か負かに関係なく)全ビットを反転させてから 1 を足せばよい。2の補数での加算は符号無しの数値と同じである(ただし、オーバーフローが発生したときの検出方法は異なる)。右表を見ればわかるとおり、127 と −128 の加算は、符号無しの 127 と 128 を加算するのと同じである。
ある数の2の補数を簡単に得る方法は以下の通りである。
例 1 | 例 2 | |
1. 右端から見ていき、最初の '1' を探す | 0101001 | 0101100 |
2. その '1' より左側のビット列を反転させる | 1010111 | 1010100 |
エクセスN
ビットパターン | エクセス127表現 | 符号無し表現 |
---|---|---|
00000000 | -127 | 0 |
00000001 | -126 | 1 |
... | ... | ... |
01111111 | 0 | 127 |
10000000 | +1 | 128 |
... | ... | ... |
11111111 | +128 | 255 |
エクセスNはバイアス表現、下駄ばき表現、あるいはオフセット・バイナリ(offset binary)とも呼ばれ、事前に決めたNという数をバイアス値として使う。ある数値は、元の値よりNだけ大きい符号無し数値として表現される。したがって、0 は N で表され、−Nはゼロが並んだビットパターンで表される。
この表現は浮動小数点数で使われている。IEEE浮動小数点標準では単精度(32ビット)の指数部は8ビットのエクセス127として定義されている。 倍精度(64ビット)では11ビットのエクセス1023である。
比較表
以下の表は 4 ビットでの各表現方法で、最大 +8 から -8 までの整数を表現したものの比較表である。
十進 | 符号無し | 符号-仮数部 | 1の補数 | 2の補数 | エクセス7 |
---|---|---|---|---|---|
+8 | 1000 | N/A | N/A | N/A | 1111 |
+7 | 0111 | 0111 | 0111 | 0111 | 1110 |
+6 | 0110 | 0110 | 0110 | 0110 | 1101 |
+5 | 0101 | 0101 | 0101 | 0101 | 1100 |
+4 | 0100 | 0100 | 0100 | 0100 | 1011 |
+3 | 0011 | 0011 | 0011 | 0011 | 1010 |
+2 | 0010 | 0010 | 0010 | 0010 | 1001 |
+1 | 0001 | 0001 | 0001 | 0001 | 1000 |
(+)0 | 0000 | 0000 | 0000 | 0000 | 0111 |
(−)0 | N/A | 1000 | 1111 | N/A | N/A |
−1 | N/A | 1001 | 1110 | 1111 | 0110 |
−2 | N/A | 1010 | 1101 | 1110 | 0101 |
−3 | N/A | 1011 | 1100 | 1101 | 0100 |
−4 | N/A | 1100 | 1011 | 1100 | 0011 |
−5 | N/A | 1101 | 1010 | 1011 | 0010 |
−6 | N/A | 1110 | 1001 | 1010 | 0001 |
−7 | N/A | 1111 | 1000 | 1001 | 0000 |
−8 | N/A | N/A | N/A | 1000 | N/A |
参考文献
- Ivan Flores, The Logic of Computer Arithmetic, Prentice-Hall (1963)
- Israel Koren, Computer Arithmetic Algorithms, A.K. Peters (2002), ISBN 1-56881-160-8
関連項目
脚注
- ↑ ドナルド・クヌース The Art of Computer Programming, Volume 2: 4.1節
cs:Dvojková soustava#Zobrazen.C3.AD_z.C3.A1porn.C3.BDch_.C4.8D.C3.ADsel de:Einerkomplement eo:Negativa kaj nenegativa nombroj en komputiko es:Complemento a uno fr:Complément à un it:Rappresentazione dei numeri relativi pt:Complemento para um th:การแทนจำนวนที่มีเครื่องหมาย vi:Biểu diễn số âm