符号付数値表現
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2023/05/10 01:49 UTC 版)
コンピュータで負の数を表す方法は、用途などにあわせいくつかある。ここでは、二進記数法を拡張して負の数を表す方法を四種類説明する(#符号-仮数部、#1の補数、#2の補数、#エクセス N)。ほとんどの場合、最近のコンピュータでは2の補数表現を使うが、他の表現が全く使われないわけではない(おそらく、最も使われている2の補数以外の表現は、浮動小数点の表現内に含まれるエクセス1023であろう)。
符号・絶対値表現
ビットパターン | 符号・絶対値表現 | 符号無し表現 |
---|---|---|
00000000 | 0 | 0 |
00000001 | 1 | 1 |
… | … | … |
01111111 | 127 | 127 |
10000000 | −0 | 128 |
… | … | … |
11111111 | −127 | 255 |
8ビットで数値を表す場合、符号は1ビット、絶対値は7ビットで表現される。この場合、絶対値の範囲は 0000000 から 1111111 まで(十進法で +0 から +127 まで)である。したがって、8ビットの符号・絶対値表現で表せる数の範囲は −127 から +127 である。
符号・絶対値表現において、0 を表す方法は 00000000 (+0) と 10000000 (−0) の2通りある。
初期の二進コンピュータ(例えば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" 、すなわちoneの複数形onesの所有格であり、「2の補数」が "two's complement"、すなわちtwoの単数形の所有格であるのと異なる。これは、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 |
- ^ ドナルド・クヌース The Art of Computer Programming, Volume 2: 4.1節
- 1 符号付数値表現とは
- 2 符号付数値表現の概要
- 3 エクセス N
- 4 参考文献
- 5 関連項目
- 符号付数値表現のページへのリンク