Java bitwise operators are low-level operators that means they work on bit level and used to manipulate individual bits of a bit pattern. Bitwise operators can be applied only on integer types i.e., byte
, short
, int
, long
, and char
.
Bitwise operators are most commonly used for testing and setting individual bits in a value. If either of the arguments to a bitwise operator is a long
, the result is a long
. Otherwise, the result is an int
.
Java's bitwise operators are ~
("bitwise complement or not operator"), &
("bitwise and"), |
("bitwise or"), ^
("bitwise xor or odd operator").
Bitwise operators cannot be used with floating-point, boolean, array, or object operands. When bitwise &
and |
operators are applied to boolean
values they behave similar to the &&
and ||
operators and yeild a boolean
value as a result. The only difference is that &
and |
operators are not evaluated in "short circuit" fashion. That is, both arguments are first evaluated before the result is computed. We will discuss short circuit evaluation again in logical operators.
Table 1 demonstrates Java bitwise operators assuming that A and B are two bits containing either 0 or 1 then following bitwise operations can be performed on A and B.
A | B | A & B | A | B | A ^ B | ~A | ~B |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 1 | 1 |
0 | 1 | 0 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 1 | 0 | 1 |
1 | 1 | 1 | 1 | 0 | 0 | 0 |
Now, let us discuss all bitwise operators one by one in more detail.
The bitwise complement (~) or bitwise NOT operator is a unary operator that inverts each bit of its single operand, converting ones to zeros and zeros to ones. For example the following program inverts all bits of b
and clears flag f
in a set of flags
by using bitwise NOT operator.
class bitwiseOperator { public static void main(String args[]) { byte b = ~12; // ~00000110 ==> 11111001 or -13 decimal int flags = 28; int f = 4; flags = flags & ~f; // Clear flag f in a set of flags, now it is 24 System.out.println("b: " + b); System.out.println("flags: " + flags); } } OUTPUT ====== b: -13 flags: 24
The bitwise AND (&) operator is a binary operator that operates on two integer operands by performing a Boolean AND operation on their individual bits. The result is 1 only if the corresponding bits are 1 in both operands. The bitwise AND is a perfect way to test if a particular bit is 1 or 0 in an integer. Following program demonstrates the bitwise AND operator.
class bitwiseOperator { public static void main(String args[]) { int flags = 28; int f = 4; // Test whether flag f is set if ((flags & f) != 0) // 011100 & 000100 ==> 000100 or 4 { System.out.println("flag f is set in flags: " + (flags & f)); } else { System.out.println("flag f is not set in flags: " + (flags & f)); } } } OUTPUT ====== flag f is set in flags: 4
The bitwise OR (|) operator is a binary operator that operates on two integer operands by performing a Boolean OR operation on their individual bits. The result is 1 if the corresponding bit is 1 in either or both of the operands. It has a zero bit only where both corresponding operand bits are zero. Following program demonstrates the bitwise OR operator.
class bitwiseOperator { public static void main(String args[]) { int flags = 28; int f = 32; // 011100 | 100000 ==> 111100 or 60 flags = flags | f; // Set flag f System.out.println("flag f is set in flags: " + flags); } } OUTPUT ====== flag f is set in flags: 60
The bitwise XOR (^) operator is a binary operator that operates on two integer operands by performing a Boolean XOR (Exclusive OR) operation on their individual bits. The result is 1 if the corresponding bits in the two operands are different. If the corresponding operand bits are both ones or both zeros, the result bit is a zero. Following program demonstrates the bitwise XOR operator.
class bitwiseOperator { public static void main(String args[]) { int num1 = 10, num2 = 7; // 00001010 ^ 00000111 ==> 00001101 or 13 int xorResult = num1 ^ num2; System.out.println("XOR of " + num1 + " and " + num2 + " is: " + xorResult); } } OUTPUT ====== XOR of 10 and 7 is: 13
Char values in Java can be converted to and from the various integral types; therefore bitwise operations can be applied on them. However, I don't see any great application of applying bitwise operations on char
types but for knowledge sake, yes, bitwise operators can be applied on char
types in Java. The following program demonstrates bitwise operations on char
variables.
class bitwiseOperator { public static void main(String args[]) { char ch1 = 'a', ch2 = 'b'; //Bitwise complement // ~97 ==> -98 System.out.println("~ch1: " + ~ch1); // Bitwise AND // 97 & 98 ==> 96 System.out.println("ch1 & ch2: " + (ch1 & ch2)); // Bitwise OR // 97 | 98 ==> 99 System.out.println("ch1 | ch2: " + (ch1 | ch2)); // Bitwise XOR // 97 ^ 98 ==> 3 System.out.println("ch1 ^ ch2: " + (ch1 ^ ch2)); } } OUTPUT ====== ~ch1: -98 ch1 & ch2: 96 ch1 | ch2: 99 ch1 ^ ch2: 3
In addition to above bitwise operators, Java provides three flavors of bitwise shift operators that are left shift (<<), right shift (>>) and zero-fill right shift (>>>). The notable difference between right shift and zero-fill right shift is that in right shift bitwise operation, the vacant bits from left side are filled by the left most bit (that is sign bit) it can be zero or one. It is done to preserve the sign of operand. Vacant bits are filled by zero, if the number is positive, or by one, if the number is negative. While in zero-fill right shift, vacant bits from left side are always filled by zero regardless of the sign. Let's assume that X is an integer of type int
containing decimal value 15 and -15, then it gives following results when different shift operations are applied (see Table 2):
Shift operators have the syntax:
var <shift operator> number of bits to be shifted
For example, X = X << 2;
X (in decimal) Before Operation |
Shift Operation |
X (in decimal) After Operation |
---|---|---|
15 | X = X << 2 | 60 |
15 | X = X >> 2 | 3 |
15 | X = X >>> 2 | 3 |
-15 | X = X << 2 | -60 |
-15 | X = X >> 2 | -4 |
-15 | x = X >>> 2 | 1073741820 |
Bitwise operators are of great help if we have to perform operations on individual bits rather than the complete number. Masking is a technique which can be used to extract a particular bit. For example, if you wish to check whether 5th bit of a given integer is 0 or 1, you can do it as
int x = 23; // fifth bit is one as binary of 23 is 10111 int fifthBit = (x & 16) / 16; System.out.println("Fifth bit of " + x +" is " + fifthBit);
We can also check whether a given integer is odd or even without applying modulus or division operation. If (x & 1)
yields 1 then odd else even.
Computing sign of a number without branching can also be done by bitwise operators. We know that if left most bit of an integer is zero then number is positive else negative. We can find out the value of left most bit that is also called Most Significant Bit (MSB).
int num = 17; int sign; sign = num >>> 31; //size of int is 32 bits in Java
We can also detect if an integer is a power of 2 as follows:
int num = 32; boolean isPowOfTwo = (num & (num -1)) == 0; System.out.println(num + " is power of two? " + isPowOfTwo);
There are many more such useful applications of bitwise operators. It is not possible for us to cover all of them in such a short text.
In this tutorial we discussed Java's bitwise and shift operators. Hope you have enjoyed reading this tutorial on various Java operators. Please do write us if you have any suggestion/comment or come across any error on this page. Thanks for reading!
Share this page on WhatsApp