シフト演算子
ビット演算子の中でも下記の3つはシフト演算子と呼ばれることもあります。
演算子 | 使用例 | 意味 |
---|---|---|
<< | a << 3 | a を 左へ3ビットシフト |
>> | a >> 3 | a を 右へ3ビットシフト(符号有り) |
>>> | a >>> 3 | a を 右へ3ビットシフト(符号無し) |
これらの3つの演算子は対象の値の各ビットを右または左へシフトします。
10進数で右または左へ数値をシフトした場合、それは数値を1/10にしたり10倍することを意味します。例えば1230を左へシフトして12300とすれば10倍したことになりますし、右へシフトして123とすれば1/10になったこととなります。同じように2進数でシフトした場合は1/2にしたり2倍したりすることを意味します。
では順に確認していきます。(int型だと面倒なので8ビットのbyte型を使って確認していきます)。
左シフト
<<演算子は対象の値を指定した数だけ左へシフトします。次の例を見てください。
byte b; b = 0x15 << 2;
変数「b」には0x15を左へ2つシフトした値が代入されます。この場合は次のような処理が行われます。
00010101 = 0x15 -------- 00101010 = 左へ1つシフト 01010100 = 左へ2つシフト
0x15を左へ2つシフトすると01010100(0x54)となります。左へシフトする場合、左側からはみ出たビットは捨てられ、シフトしたことによて空いた右側には0が詰められます。
右シフト(符号有り)
>>演算子は対象の値を指定した数だけ右へシフトします。次の例を見てください。
byte b; b = 0x2A >> 2;
変数「b」には0x2Aを右へ2つシフトした値が代入されます。この場合は次のような処理が行われます。
00101010 = 0x2A -------- 00010101 = 右へ1つシフト 00001010 = 右へ2つシフト
0x2Aを右へ2つシフトすると00001010(0x0A)となります。右へシフトする場合、右側からはみ出たビットは捨てられます。そしてシフトによって空いた左側には元のビットが1だった場合は1が詰められ、元のビットが0だった場合は0が詰められます。この結果、右シフトしても負の整数は符号がそのままで数値が1/2となります。
下記は最上位ビットが1だった場合の例です。
10100011 = 0xA3 -------- 11010001 = 右へ1つシフト 11101000 = 右へ2つシフト
右へシフトした時に空いた一番左側のビットには、シフトする前が1だったので1で詰められています。
右シフト(符号無し)
>>>演算子は対象の値を指定した数だけ右へシフトします。>>演算子との違いはシフト前の一番左のビットが何であっても右へシフトした時に一番左のビットは常に0で詰められます。次の例を見てください。
byte b; b = 0xA3 >>> 2;
変数「b」には0xA3を右へ2つシフトした値が代入されます。この場合は次のような処理が行われます。
10100011 = 0xA3 -------- 01010001 = 右へ1つシフト 00101000 = 右へ2つシフト
0x2Aを右へ2つシフトすると00101000(0x28)となります。この演算子の場合は、右シフトによって1/2となるということよりも純粋にビットを右へシフトさせたい場合などに使用されます。
サンプル
では簡単なサンプルで試してみます。
class JSample9_1{ public static void main(String args[]){ byte b; b = 8 << 3; System.out.print("8 << 3 = "); System.out.println(b); b = -10 << 2; System.out.print("-10 << 2 = "); System.out.println(b); b = 8 >> 1; System.out.print("8 >> 1 = "); System.out.println(b); b = -20 >> 2; System.out.print("-20 >> 2 = "); System.out.println(b); } }
コンパイル後に実行すると次のように表示されます。
左へ一度シフトすると数値が2倍になり、右へ一度シフトすると1/2になっていることが分かります。
( Written by Tatsuo Ikura )