整数の表現形式

本(C/C++セキュアコーディング)を読んだメモ.
むかぁーし, コンピュータアーキテクチャかなんかの講義でやった気がするけど完全に忘れてる.



整数の表現方法は, 主に3つ.

  • 符号付き絶対値
  • 1の補数
  • 2の補数

現在最も優勢なのは, 2の補数による表現形式で, ほぼ全てのコンピュータがこれを使用してるとのこと.

符号付き絶対値

最高位ビットを符号として扱う形式.
0が正, 1が負を表す.

 00000111 → 111 = 7, 最高位ビット = 0, よって, +7.
 10000111 → 111 = 7, 最高位ビット = 1, よって, -7.

1の補数

負の数は, 対応する正の数の各ビットを反転させて表す形式.
正の数のすべての1を0に, すべての0を1にすると負の数となる.

 00000111 → +7
 11111000 → -7

2の補数

1の補数表現に1を加えて作る形式.
符号付き絶対値と1の補数だと, 0の表現方法が2種類存在するため計算機での取り扱いが不便.
2の補数だと, 0の表現方法が1つしかないから便利.
符号は最高位ビットで表現される.
(0だと正, 1だと負.)

 00000111 → +7
 11111001 → -7

プログラム作って適当に実験

int main( int argc, char *argv[] )
{
  int i;
  for( i=0; i<8; i++ ){
    printf( "%3d %3d %8x %8x\n", i, ~(i)+1, i, ~(i)+1 );
  }

  putchar( '\n' );

  for( i=-1; i>-9; i--){
    printf( "%3d %3d %8x %8x\n", i, ~(i)+1, i, ~(i)+1 );
  }

  return 0;
}

これの結果.

[khiker@khlin001 ~/<1>c/bit]$ gcc -Wall test_sign1.c -o test_sign
[khiker@khlin001 ~/<1>c/bit]$ ./test_sign
  0   0        0        0
  1  -1        1 ffffffff
  2  -2        2 fffffffe
  3  -3        3 fffffffd
  4  -4        4 fffffffc
  5  -5        5 fffffffb
  6  -6        6 fffffffa
  7  -7        7 fffffff9

 -1   1 ffffffff        1
 -2   2 fffffffe        2
 -3   3 fffffffd        3
 -4   4 fffffffc        4
 -5   5 fffffffb        5
 -6   6 fffffffa        6
 -7   7 fffffff9        7
 -8   8 fffffff8        8

これでいいのかな.
反転してから1足すのに, ずっと~(i+1)やってて, でねぇーとかほざいてた.