Javaには、整数型(byte、short、int、long、char)のビットを操作するための演算子があります。
ビットを左へシフトするには<<を、右へシフトするには>>を使います。
// Shift two places to the left
0b0000_1011 << 2;
// # => 0b0010_1100
// Shift two places to the right
0b0000_1011 >> 2;
// # => 0b0000_0010
>>は、挿入されるビットが符号ビットと同じであるため、符号付きシフト、または算術シフト演算子とも呼ばれます。
これは最上位ビットのことで、値が正なら0、負なら1になります。
<<で左へシフトするときは、常に右側に0が挿入されます。
// Shift 2 places to the right preserves the sign
// The binary value is two's complement of 0b0000_0110 (or 0x00000026), so the binary representation will be
// 1000_0000_0000_0000_0000_0000_0010_0110
int value = -0x7FFFFFDA;
// Shift two places to the right, preserving the sign bit
value >> 2;
// # => 1110_0000_0000_0000_0000_0000_0000_1001
右へシフトするときに0を挿入したい場合は、代わりに>>>を使います。
シフト時に0を挿入することを論理シフトともいいます。
// Shift two places to the right, inserting 0s on the left
value >>> 2;
// # => 0010_0000_0000_0000_0000_0000_0000_1001
ビット単位のAND演算子(&)は、2つの値を受け取り、各ビットに対してANDを行います。
1つ目の値の各ビットを、2つ目の値の同じ位置にあるビットと比較します。
どちらも1なら、結果のビットは1になります。
そうでなければ、結果のビットは0です。
0b0110_0101 & 0b0011_1100;
// # => 0b0010_0100
ビット単位のOR演算子(|)は、2つの値を受け取り、各ビットに対してORを行います。
1つ目の値の各ビットを、2つ目の値の同じ位置にあるビットと比較します。
どちらかのビットが1なら、結果のビットは1になります。
そうでなければ0です。
0b0110_0101 | 0b0011_1100;
// # => 0b0111_1101
ビット単位のXOR演算子(^)は、2つの値に対してビット単位のXORを行います。
ビット単位のAND演算子やOR演算子と同じように、1つ目の値の各ビットを、2つ目の値の同じ位置にあるビットと比較します。
どちらか一方だけが1なら、結果のビットは1になります。
そうでなければ0です。
0b0110_0101 ^ 0b0011_1100;
// # => 0b0101_1001
~)最後に、ビット単位のNOT演算子(~)は各ビットを反転させます。
これまでの演算子と違い、これは単項演算子で、1つの値にだけ働きます。
~0b0110_0101;
// # => 0b1001_1010