ビット演算>右シフト

右シフトとは、下図のように、各ビットをひとつ右にずらし、最上位ビットに0を入れることだ。最下位ビットの値は捨てられる。
ただし、シフトされる対象が符号付きの場合、最上位ビットの値はそのまま残る。

temp

1ビット 左シフトとが2倍することだったことの裏返しで、1ビット右シフトは2で割る(余りは切り捨て)ことと同等だ。符号付き整数を右シフトした場合、最上位ビットがそのまま残るのは、マイナスの数値の符号を維持するためだ。

C/C++ では 二項演算子 >> が右ビットシフトを表す。
シフトするビット数は1だけとは限らず、「x >> 2」 の様にシフトするビット数を付加して記述することが出来る。

int x = 0xff00 >> 4;  // 0xff00 を4ビットシフトした値を x に代入
x >>= 2;  //  x を 2ビット左シフトし、それを x に代入

上記は C/C++ での右シフトの使用例だ。

前稿 で、左シフトを使って、全ビットを検査するコードを示したが、左シフトでは最下位ビットから最上位ビットに向かって、順に処理を行うことになる。場合によっては、最上位ビットから下位ビットに向かって、処理を行いたい場合がある。その場合は、右シフトを用いる。

int x = 何らかの値;
for(unsigned int mask = 0x80000000; mask != 0; mask>>=1) {
  if( (x & mask) != 0 ) {  // x の mask ビットが立っていたら
    何らかの処理;
  }
}

注意すべきは、mask は符号付きではなく、符号なし(unsigned)を用いないといけないという点だ。符号付だと、最上位ビットが残ってしまい、うまくループしてくれない。

演習問題:

  1. int x = 100; を宣言し、x を1ビット右シフトした値を表示し、値が半分になっていることを確認しなさい
  2. int x = -100; を宣言し、x を1ビット右シフトした値を表示し、値が半分になっていることを確認しなさい
  3. int x; に何らかの値が入っているとき、中身のビットを逆順にするコードを書きなさい。例:0xff00aa03 → 0xc05500ff;

演習問題解答例