シフト演算を使うときに注意する事があります。それは、シフトする変数が signed か unsigned かで右シフトの結果が変わる場合があるということです。これは、 signed の変数をシフトするときは算術シフトが、unsigned の変数をシフトするときは論理シフトが 用いられる為起こります。論理シフトはかなり直感的でわかりやすいものになります。次に論理シフトを行う前と行 った後の、メモリの中に保存されているデータのビットイメージを書きます。int main(int argc, char* argv[])
{
unsigned int a = 0xf0ffffff; /* 処理系によって桁が異なる。 sizeof(int)=2byteの時は 0xf0ff で行う*/
int b = (int)(b);printf("a = %08x , b = %08x\n",a,b);
a >>= 4;
b >>= 4;
printf("a = %08x , b = %08x\n",a,b);
return 0;
}
論理シフト 0x78 << 1ビット列が右に1移動したのがわかりますね。全体を右にシフトし、空いた左に0を無条件 で挿入するのが論理シフトです。シフト前(16進:0x78 10進:120)論理シフト 0xF0 >> 1
01111000
シフト後(16進:0xF0 10進:240)
11110000シフト前(16進:0xF0 10進:240)
11110000
シフト後(16進:0x78 10進:120)
01111000
算術シフト 0x78 << 1ビットの変化には法則があります。シフトしても、最左端のビットは変化しないのです。シフト前(16進:0x0F 10進:120)算術シフト 0xF0 >> 1
01111000
シフト後(16進:0x60 10進:96) 注:オーバーフローが起きている
01110000シフト前(16進:0xF0 10進:−16)
11110000
シフト後(16進:0xF8 10進:−8)
11111000