C言語におけるビットシフト演算子と符号付き数値表現

符号付き整数の内部表現

コンピュータ内部で整数を表現する方法にはいくつかの方式があります。特にC言語では、整数は補数形式(2の補数)として保存されます。以下に3つの表現方式を説明します:

  • 原符号(Sign-Magnitude): 最上位ビット(MSB)が符号を表し、0は正、1は負。
  • 1の補数: 負数は原符号の数値部を反転したもの。
  • 2の補数: 1の補数に1を加えた形式。現在のコンピュータは主にこの形式を使用。

具体例(8ビット整数)

数値原符号1の補数2の補数
5000001010000010100000101
-5100001011111101011111011
-127100000011111111011111111

C言語のビットシフト演算

C言語では2進数の操作にシフト演算子を使用します。重要なのは、シフト演算は常に補数形式に対して行われるという点です。

左シフト演算子 `<<`

左シフトは、指定されたビット数だけ左にシフトし、右端に0を挿入します。


int value = 5; // 2進数: 00000101
int shifted = value << 2; // 00010100 (10進数: 20)

右シフト演算子 `>>`

右シフトには2種類あります:

  • 論理右シフト: 符号に関係なく左端に0を挿入(符号なし整数型で使用)。
  • 算術右シフト: 符号ビットを保持し、左端に符号ビットと同じ値を挿入(符号付き整数型で使用)。

例:算術右シフト


int value = -10; // 2の補数: 11111111111111111111111111110110
int shifted = value >> 2; // 11111111111111111111111111111101 (-3)

例:論理右シフト


unsigned int value = 250; // 2進数: 11111010
unsigned int shifted = value >> 2; // 00111110 (62)

シフト演算の注意点

  • C言語では、負数に対する右シフトの動作は処理系依存です。
  • シフトするビット数が変数で指定される場合、その値がデータ型のビット数を超えないように注意してください。
  • シフト演算は高速な乗除算に利用できますが、可読性を考慮し、コメントで説明を加えると良いです。

応用例

  • 高速な乗除: 左シフトで2のべき乗の乗算、右シフトで除算。
  • ビットマスク: 特定のビットを抽出、設定、クリアする。
  • ネットワークプロトコル: パケット内のフィールドを抽出。
  • 画像処理: ピクセルデータの解析や変換。

ビット抽出の例


unsigned int data = 0x12345678;
unsigned int lower16 = data & 0xFFFF; // 下位16ビット抽出
unsigned int upper16 = data >> 16;   // 上位16ビット抽出

タグ: C言語 ビット演算 シフト演算 2進数 符号付き整数

5月18日 08:20 投稿