ビット演算子は主にオペランドのバイナリ ビットを演算するために使用されます。ビット単位の演算は、各バイナリ ビット (ビット) に対して実行される計算を表し、オペランドと演算結果は両方とも整数値です。
Java 言語のビット演算子は、ビット論理演算子とシフト演算子の 2 つのカテゴリに分類され、各カテゴリに含まれる演算子については以下で詳しく説明します。
ビットごとの論理演算子
& (and)、| (or)、~ (not)、および ^ (排他的論理和) の 4 ビット論理演算子があります。単項演算子である ~ (ビットごとの否定) を除き、残りは二項演算子です。それらの基本的な使用法を表 1 に示します。
オペレーター | 意味 | 例 | 結果 |
---|---|---|---|
& | ビット単位の論理積演算 (AND) | 4&5 | 4 |
| | ビット単位の論理和演算 (OR) | 4 | 5 | 5 |
^ | ビットごとの排他的論理和 (XOR) | 4^5 | 1 |
~ | ビットごとの否定演算 (NOT) | ~4 | -5 |
ビット単位の AND 演算子
ビットAND演算子は&
であり、その演算規則は、演算に関わる数値の下位を並べ、上位を0で埋め、対応する2進数のビットが同時に1であれば、演算結果がは 1、それ以外の場合は 0 です。したがって、任意の数値と 0 をビットごとに AND 演算した結果は 0 になります。
たとえば、次のような式です。
100&0
結果は 0 です。
以下は、2 つの非ゼロ数値に対してビットごとの AND 演算を実行するプロセスです。
int x = 5, y = 12; // 2つの数を保存する整数変数を作成する
int z = x & y; // これら2つの数にビットAND演算を行い、その結果をzに保存する
これら 2 行のステートメントが実行されると、変数 Z の値は 4 になります。
ビットごとの OR 演算子
ビット OR 演算子は|
であり、その演算規則は、演算に含まれる数値を下位から揃え、上位が足りない場合はゼロ埋めされます。対応する 2 進ビットのうち 1 つだけが 1 の場合、結果は 1 になります。対応する 2 進ビットがすべて 0 の場合、結果は 0 になります。
以下は、ビットごとの OR 演算子を使用した式です。
11|7
演算結果は 15 です
ビットごとの XOR 演算子
ビット排他的 OR 演算子は^
であり、その演算規則は次のとおりです: 演算に含まれる数値は下位に整列され、上位はゼロを埋めるのに不十分です。対応する 2 進数のビットが同じ (両方とも 0) の場合、または 1 を同時に)、結果は 0、対応するバイナリ ビットが同じでない場合、結果は 1 になります。
以下は、ビットごとの XOR 演算子を使用した式です。
11^7
ヒント: 一部の高級言語では、演算子^
がべき乗演算子として使用されるため、その区別に注意する必要があります。
ビット否定演算子
ビット反転演算子は~
で、その演算規則は、オペランドを 1 つだけ演算し、オペランドの 2 進数の 1 を 0 に変更し、0 を 1 に変更します。
以下は、ビットごとの否定演算子を使用した式です。
~10
演算結果は 65525 となり
次のプログラムを使用して、この操作の結果を確認できます。
int i = 10;
System.out.printf("%d \n",〜i);
上記のプログラムをコンパイルして実行すると、出力が 65525 ではなく -11 であることがわかります。これは、否定後の結果が 16 進数であり、上記のプログラムでは出力を 10 進数に変換するために %d が使用されているためです。
次のステートメントを使用すると、16 進数の結果を表示できます。
int i=10;
System.out.printf("%x \n",~i);
//変数iに値10を代入します。
System.out.printf(「%x \ n」、〜i);: iのビット反転値の16進数表記を出力します。
出力結果は fff5 であることがわかります。バイナリに変換すると 1111111111110101 になります。この 2 進数の最上位ビットは 1 で、数値が負であることを示します。最上位ビットに加えて、ビット単位の反転に 1 を加算して、元のバイナリ コード 1000000000001011 (10 進数で -11) を取得します。
注: ビット演算子のオペランドには、整数または文字データとそのバリアントのみを使用できます。float、double、long などの複合型は使用できません。
シフト演算子
シフト演算子は、指定された 2 進数の桁数だけオペランドを特定の方向 (左または右) に移動するために使用されます。表 2 に、Java 言語の 2 つの変位演算子をリストします。これらは両方とも両眼演算子です。
オペレーター | 意味 | 例 | 結果 |
---|---|---|---|
» | 右シフト演算子 | 8»1 | 4 |
« | 左シフト演算子 | 9«2 | 36 |
左シフト演算子
左シフト演算子は«
で、その演算規則は次のとおりです。すべての数値を 2 進形式の対応する桁数だけ左にシフトし、上位ビットを削除 (破棄) し、下位ビットの空いた部分を 0 で埋めます。
元の数値のすべての 2 進ビットが 1 ビット左にシフトされます。元々左側にあった最上位ビット 0 はシフトアウトされて破棄され、最後に 0 が追加されてビットが構成されます。最終結果は 22 で、これは元の数値の 2 倍に相当します。
右シフト演算子
右シフト演算子は»
で、その演算規則は次のとおりです。すべての数値をバイナリ形式で対応する桁数だけ右に移動し、下位ビットを削除 (破棄) し、上位ビットをゼロで埋めます。
元の数値のすべての 2 進ビットが 1 ビット右にシフトされます。もともと右側にあった最下位ビット 1 はシフトアウトされて破棄され、最上位ビットに 0 が追加されて補われます。最終結果は 5 で、これは元の数値を 2 で割った結果と等価です。
すべての 2 項ビット演算子には、代入とビット演算を組み合わせた短縮形式があります。複合ビット単位の代入演算子は、ビット単位の論理演算子およびシフト演算子と組み合わせた代入演算子で構成されます。表 3 は、複合ビット割り当て演算子の組み合わせを示しています。
オペレーター | 意味 | 例 | 結果 |
---|---|---|---|
&= | ビット単位と代入 | 数値 1 &= 数値 2 | num 1=num 1 & num2 と同等 |
|= | ビット単位または代入 | 数値 1 |= 数値 2 | num 1=num 1 | num2 と同等 |
^= | ビット単位の XOR 割り当て | 数値 1 ^= 数値 2 | num 1=num 1 ^ と同等 番号2 |
-= | ビットごとの逆代入 | 数値1 -= 数値2 | num 1=num 1 – num2 と同等 |
«= | ビット単位の左シフト代入 | 数値1 «= 数値2 | num 1=num 1 « num2 と同等 |
»= | ビット単位の右シフト代入 | 数値 1 »= 数値 2 | num 1=num 1 » num2 と同等 |
次のプログラムは、いくつかの int 変数を定義し、ビット割り当ての短縮形を使用して、計算された値を対応する変数に割り当てます。
int a = 1;
int b = 2;
int c = 3;
a &= 4;
a |= 4;
a ^= c;
a -= 6;
b >>= 1;
c <<= 1;
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
このプログラムの出力は次のとおりです。
a = 1
b = 1
c = 6