符号付数値表現

出典: フリー百科事典『ウィキペディア(Wikipedia)』

これはこのページの過去の版です。119.171.8.203 (会話) による 2021年3月4日 (木) 03:32個人設定で未設定ならUTC)時点の版 (→‎1の補数)であり、現在の版とは大きく異なる場合があります。

符号付数値表現(ふごうつきすうちひょうげん)の記事では、コンピュータシステムにおける数の表現(コンピュータの数値表現)において、負の範囲も含んで(正の数と負の数の記事も参照)を表現する方法を解説する。 コンピュータで負の数を表す方法は、用途などにあわせいくつかある。ここでは、二進記数法を拡張して負の数を表す方法を四種類説明する(符号-仮数部、1の補数、2の補数、エクセスN)。ほとんどの場合、最近のコンピュータでは2の補数表現を使うが、他の表現が全く使われないわけではない(おそらく、最も使われている2の補数以外の表現は、浮動小数点の表現内に含まれるエクセス1023であろう)。

符号-仮数部

8 ビット 符号-仮数部
ビットパターン 符号-仮数部表現 符号無し表現
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の補数

8 ビット 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]

IPv4のヘッダーチェックサムは1の補数を使っている。

指数-仮数部表現で負数の仮数部をビット毎に反転させると、1の補数表現に変換される。

2の補数

8 ビット 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

8 ビット エクセス127
ビット列 エクセス127表現
としての解釈
符号なし表現
としての解釈
00000000 −127 0
00000001 −126 1
... ... ...
01111111 0 127
10000000 +1 128
... ... ...
11111111 +128 255

エクセスN は、事前に定めた正の整数Nバイアス値(偏り)として用いる表現。ある整数は、元の値よりN だけ大きい符号なし整数として表現される。例えば、値 0 は N として表され、値 −N は 0 として表される。N として、2m −1 がよく用いられる。バイアス表現下駄ばき表現、またはオフセット・バイナリ (offset binary) とも呼ばれる。

この表現は、浮動小数点数の指数部でよく用いられている。IEEE浮動小数点標準では、単精度(32ビット)の指数部は8ビットのエクセス127として定義されている。倍精度(64ビット)では11ビットのエクセス1023である。

比較表

以下の表は 4 ビットでの各表現方法で、最大 +8 から −8 までの整数を表現したものの比較表である。

4ビット整数表現
十進 符号無し 符号-仮数部 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

関連項目

脚注

  1. ^ ドナルド・クヌース The Art of Computer Programming, Volume 2: 4.1節