符号付き整数の定義と表現:符号と大きさ・2の補数の比較
符号付き整数の基本と表現法をわかりやすく解説。符号と大きさと2の補数の違い、利点・欠点、実装上の注意点を徹底比較。
符号付き整数表現は、負の整数を2進数で表現する際の問題を解決するために使用される。2進数の負の符号(-)を単純に「別の記号」で格納しようとすると、符号と数値の区別や演算時の扱いに矛盾が生じる。ビット列だけを扱うコンピュータには「このビットが符号か数値か」を自明に判断する手段がないからであり、単純にマイナスをオフ、プラスをオンとするだけでは都合が悪い。
この問題を解決するために、コンピュータ設計者は主に次の2つの方法を考案した:符号と大きさ(sign-and-magnitude)と2の補数(two's complement)。どちらも符号付き数値をビット列で表現するための代替方式であり、それぞれに長所と短所がある。
符号と大きさ(sign-and-magnitude)
最上位ビット(MSB)を符号ビットとして使い、残りのビットで絶対値(大きさ)を表す方式。MSBが0なら正、1なら負を表す。
例えば8ビットの場合:
- +5 = 00000101
- -5 = 10000101
特徴:
- 表現できる範囲(nビット):-(2^{n-1}-1) 〜 +(2^{n-1}-1)。例:8ビットなら -127 〜 +127。
- 0が2種類ある(+0 = 000...0、-0 = 100...0)。
- 減算・加算をハードウェアで直接行うときに例外処理が必要になる場合があり、回路が複雑になる。
2の補数(two's complement)
負の数を表すには、その絶対値のビットを反転(各ビットを0↔1)してから1を加える(=1の補数に1を足す)という操作で表現する方式。現在のほとんどの汎用プロセッサやプログラミング言語で整数表現として採用されているのがこの方式である。
例(8ビット):
- +5 = 00000101
- -5 = 11111011 (00000101 を反転 → 11111010、そこに 1 を足す → 11111011)
特徴:
- 表現できる範囲(nビット):-2^{n-1} 〜 2^{n-1}-1。例:8ビットなら -128 〜 +127(負側に1つ多い)。
- 0 はただ一つ(000...0)。
- 符号付きの加減算を通常の2進加算でそのまま実行できるため、ハードウェアが単純で高速。オーバーフローは最上位ビットの変化やキャリーの扱いで検出する。
- 数値の符号反転(負にする)操作は「ビット反転+1」で簡単に行える。
符号と大きさ と 2の補数 の比較
- 実装の容易さ:2の補数は加算器だけで符号付き加減算を扱えるためハードウェア実装が簡単。符号と大きさは加算・減算で特別処理が必要になる。
- 表現の一意性:2の補数は0が一意。符号と大きさは+0と-0が存在し、不便になる場面がある。
- 範囲:2の補数は負側に1つ大きな絶対値(例:-128)が表現できるが、これはオーバーフローの取り扱いで注意が必要。
- 人間にとっての直感性:符号と大きさは十進の手書き表現に似て理解しやすいが、計算機内部の演算効率では2の補数に劣る。
実装上の注意点
- 桁あふれ(オーバーフロー):2の補数でもオーバーフローは起きる(例:最大正数 + 正数 → 負になってしまう)。オーバーフロー検出にはキャリーや符号ビットの変化を使う。
- 符号拡張(sign extension):ビット幅を増やすとき、2の補数では符号ビット(MSB)を上位ビットに複製することで値を維持できる。符号と大きさでも同様に符号ビットを複製するが、処理は一貫しているか確認が必要。
- 負の最小値の取り扱い:2の補数では負の最小値(例:8ビットなら-128)を正に反転しようとすると範囲外になり、単純な符号反転では正しい値にならない点に注意。
まとめ:符号と大きさは表現が直感的だがハードウェア処理が複雑で0が二重になる。一方で2の補数は演算回路が単純で効率的なため、現代のコンピュータでは標準的に採用されている方式である。
サイン&マグニチュード
Sign and Magnitudeは、数値が負の場合、最上位ビット(MSB - 1桁目)を1に変更し、数値を1つ減らすなどの動作をします。
0000 0010 (2)
になる
1000 0010 (-2)
負の2進数を格納するこの方法は、以下の理由でうまくいきません。
- 二進数演算が効かない
- まず、ある言語のコンパイラがどの記憶機構を使っているかを知る必要がある。
1の補数
1の補集合は、例えば、1を0に、0を1に入れ替えることで機能します。
0000 0010 (2)
になる
1111 1101 (-2)
符号-振幅法と同様に、最上位ビットが1であるため、簡単に負の数と定義されます。
2の補数
2の補集合は、ネガを保存する方法としてはより難しい。そのために3つのステップがあります。
- 正の2進数(例:8base 10 = 0000 1000base 2)を求めます。
- 1を0に、0を1に入れ替える(例:0000 1000base 2が1111 0111base 2になる)。
これは「ビットの反転」と呼ばれるもので、元の基数2の表現に論理的NOTを適用することです。
- 1を加算する(例:1111 0111base 2 + 1base 2 = 1111 1000base 2)。
この方式が好まれるのは
- 符号と大きさのようなもので、負の数は1から始まり、正の数は0から始まる。
- 2進法の演算はうまくいく。
- 0の値は1つだけです(0000 0000base 2)。
百科事典を検索する