Java defines several bitwise operators that can be applied to the integer types, long, int, short, char, and byte. These operators act upon the individual bits of their operands
Operator | Result |
---|---|
~ | Bitwise unary NOT |
& | Bitwise AND |
| | Bitwise OR |
^ | Bitwise exclusive OR |
>> | Shift right |
>>> | Shift right zero fill |
<< | Shift left |
&= | Bitwise AND assignment |
|= | Bitwise OR assignment |
^= | Bitwise exclusive OR assignment |
>>= | Shift right assignment |
>>>= | Shift right zero fill assignment |
<<= | Shift left assignment |
The Bitwise Logical Operators
The bitwise logical operators are &, |, ^, and ~. The following table shows the outcome of each operation. In the discussion that follows, keep in mind that the bitwise operators are applied to each individual bit within each operand
A | B | A | B | A & B | A ^ B | ~A |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 1 |
1 | 0 | 1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 | 0 |
The Bitwise NOT
Also called the bitwise complement, the unary NOT operator, ~, inverts all of the bits of its operand. For example, the number 42, which has the following bit pattern
00101010
becomes
11010101
The Bitwise AND
The AND operator, &, produces a 1 bit if both operands are also 1. A zero is produced in all other cases
00101010 42
& 00001111 15
00001010 10
The Bitwise OR
The OR operator, |, combines bits such that if either of the bits in the operands is a 1, then the resultant bit is a 1
00101010 42
| 00001111 15
00101111 47
The Bitwise XOR
The XOR operator, ^, combines bits such that if exactly one operand is 1, then the result is 1. Otherwise, the result is zero. The following example shows the effect of the ^. This example also demonstrates a useful attribute of the XOR operation. Notice how the bit pattern of 42 is inverted wherever the second operand has a 1 bit. Wherever the second operand has a 0 bit, the first operand is unchanged.
00101010 42
^ 00001111 15
00100101 37
Using the Bitwise Logical Operators
class BitLogic {
public static void main(String args[]) {
String binary[] = {
"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
};
int a = 3; // 0 + 2 + 1 or 0011 in binary
int b = 6; // 4 + 2 + 0 or 0110 in binary
int c = a | b;
int d = a & b;
int e = a ^ b;
int f = (~a & b) | (a & ~b);
int g = ~a & 0x0f;
System.out.println(" a = " + binary[a]);
System.out.println(" b = " + binary[b]);
System.out.println(" a|b = " + binary[c]);
System.out.println(" a&b = " + binary[d]);
System.out.println(" a^b = " + binary[e]);
System.out.println("~a&b|a&~b = " + binary[f]);
System.out.println(" ~a = " + binary[g]);
}
}
a = 0011
b = 0110
a|b = 0111
a&b = 0010
a^b = 0101
~a&b|a&~b = 0101
~a = 1100
The Left Shift
The left shift operator, <<, shifts all of the bits in a value to the left a specified number of times. It has this general form
value << num
Example
Left shifting a byte value.
class ByteShift {
public static void main(String args[]) {
byte a = 64, b;
int i;
i = a << 2;
b = (byte) (a << 2);
System.out.println("Original value of a: " + a);
System.out.println("i and b: " + i + " " + b);
}
}
Original value of a: 64
i and b: 256 0
The Right Shift
The right shift operator, >>, shifts all of the bits in a value to the right a specified number of
times. Its general form is shown here:
value >> num
11111000 –8
>>1
11111100 –4
The Unsigned Right Shift
The >>> operator is often not as useful as you might like, since it is only meaningful for 32- and 64-bit values. Remember, smaller values are automatically promoted to int in expressions. This means that sign-extension occurs and that the shift will take place on a 32-bit rather than on an 8- or 16-bit value. That is, one might expect an unsigned right shift on a byte value to zero-fill beginning at bit 7. But this is not the case, since it is a 32-bit value that is actually being shifted. The following program demonstrates this effect
Unsigned shifting a byte value
class ByteUShift {
static public void main(String args[]) {
char hex[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
byte b = (byte) 0xf1;
byte c = (byte) (b >> 4);
byte d = (byte) (b >>> 4);
byte e = (byte) ((b & 0xff) >> 4);
System.out.println(" b = 0x"
+ hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
System.out.println(" b >> 4 = 0x"
+ hex[(c >> 4) & 0x0f] + hex[c & 0x0f]);
System.out.println(" b >>> 4 = 0x"
+ hex[(d >> 4) & 0x0f] + hex[d & 0x0f]);
System.out.println("(b & 0xff) >> 4 = 0x"
+ hex[(e >> 4) & 0x0f] + hex[e & 0x0f]);
}
}
Bitwise Operator Compound Assignments
All of the binary bitwise operators have a compound form similar to that of the algebraic operators, which combines the assignment with the bitwise operation.
a = a >> 4;
a >>= 4;