ビット演算子

広告

整数の値に対してビット単位で処理を行うために用意されているのがビット演算子です。次の演算子が用意されています。

演算子使用例意味
&a & 0xFF00FF00a と 0xFF00FF00のビットAND
|a | 0xFF00FF00a と OxFF00FF00のビットOR
^a ^ 0xFF00FF00a と OxFF00FF00のビットXOR
~~aa のビット反転(ビットNOT)
<<a << 3a を 左へ3ビットシフト
>>a >> 3a を 右へ3ビットシフト(符号有り)
>>>a >>> 3a を 右へ3ビットシフト(符号無し)

数値を2進数の形式で表示し、各ビットに対して演算を行います。例えばint型は32ビットの値を取りますので次のように表示することができます。

0x3F30A5A5

0011 1111 0011 0000 1010 0101 1010 0101
---- ---- ---- ---- ---- ---- ---- ----
 3    F    3    0    A    5    A    5

0x3F30A5A5という16進数で表記されたint型の数値は2進数で表すと00111111001100001010010110100101となります。ビット演算子を使用すると2進数で表された各ビットに対して操作を行う事ができます。

では順に確認していきます。(int型だと面倒なので8ビットのbyte型を使って確認していきます)。

※「<<」「>>」「>>>」の3つの演算子については次のページで説明します。

ビットAND

ビットANDは演算子の左辺と右辺の同じ位置にあるビットを比較して、両方のビットが共に「1」の場合だけ「1」にします。次の例を見てください。

byte b;
b = 0x55 & 0x0F;

変数「b」には0x55と0x0FのビットANDした結果が代入されます。この時、次のような処理が行われます。

01010101  = 0x55
00001111  = 0x0F
--------
00000101  = 0x05

0x55と0x0Fをそれぞれ2進数で表します。そして各ビットを比較し両方のビットが「1」の場合だけ「1」となり、それ以外の場合は全て「0」となります。結果として00000101(0x05)という値が変数「b」には代入されることになります。

ビットOR

ビットORは演算子の左辺と右辺の同じ位置にあるビットを比較して、どちらか一つでもビット「1」の場合に「1」にします。次の例を見てください。

byte b;
b = 0x55 | 0x0F;

変数「b」には0x55と0x0FのビットORした結果が代入されます。この時、次のような処理が行われます。

01010101  = 0x55
00001111  = 0x0F
--------
01011111  = 0x5F

0x55と0x0Fをそれぞれ2進数で表します。そして各ビットを比較しどちらかのビットが「1」の場合は「1」に、両方のビットが「0」の場合は「0」にします。結果として01011111(0x5F)という値が変数「b」には代入されることになります。

ビットXOR

ビットXORは演算子の左辺と右辺の同じ位置にあるビットを比較して、どちらかのビットが一つだけ「1」の場合に「1」にします。次の例を見てください。

byte b;
b = 0x55 ^ 0x0F;

変数「b」には0x55と0x0FのビットXORした結果が代入されます。この時、次のような処理が行われます。

01010101  = 0x55
00001111  = 0x0F
--------
01011010  = 0x5A

0x55と0x0Fをそれぞれ2進数で表します。そして各ビットを比較しどちらかのビット一つだけが「1」の場合には「1」に、両方のビットが「1」であるか両方のビットが「0」の場合は「0」にします。結果として01011010(0x5A)という値が変数「b」には代入されることになります。

ビットNOT

ビットNOTは演算子の右辺の値の各ビットを反転(0なら1に、1なら0にする)させます。次の例を見てください。

byte b;
b = ~0x55;

変数「b」には0x55をビットNOTした結果が代入されます。この時、次のような処理が行われます。

01010101  = 0x55
--------
10101010  = 0xAA

0x55を2進数で表します。そして各ビットを「0」なら「1」に、「1」なら「0」にします。結果として10101010(0xAA)という値が変数「b」には代入されることになります。

サンプル

では簡単なサンプルで試してみます。

JSample8_1.java

class JSample8_1{
  public static void main(String args[]){
    byte b;

    b = 0x55 & 0x0F;
    System.out.print("0x55 & 0x0F = ");
    System.out.printf("0x%02x¥n", b);

    b = 0x55 | 0x0F;
    System.out.print("0x55 | 0x0F = ");
    System.out.printf("0x%02x¥n", b);

    b = 0x55 ^ 0x0F;
    System.out.print("0x55 ^ 0x0F = ");
    System.out.printf("0x%02x¥n", b);

    b = ~0x55;
    System.out.print("~0x55 = ");
    System.out.printf("0x%02x¥n", b);
  }
}

コンパイル後に実行すると次のように表示されます。

p8-1

※プログラムの中で使っている「System.out.printf」は16進数の形式で画面に出力するために使用しています。

( Written by Tatsuo Ikura )