Java Bitwise operators
Java provides six bitwise operators (&, |, ^, ~, <<, and >>) that manipulate the individual bits of integer values directly. They are faster than arithmetic operators for certain tasks and are essential for flag management, bitmask operations, and low-level optimisation. This article covers all operators including the unsigned right shift (>>>), with practical examples.
Bitwise operators are used to perform bit manipulation of individual bits of a number.
We can perform bitwise operations on any integral types such as intcharshort
- Bitwise operators are very powerful to make efficient use of space when representing data.
- Bitwise operators can be seen in solutions to many different problems in fields such as networking, gaming, data encryption, data compression and systems programming.
For example, if we have to represent (x, y) coordinates in a 2D window of size, to specify each number in coordinate 10 bits are enough (binary representation for the max number 1000 is 1111101000) and just with 20 bits (x,y) coordinate can be specified. If we use1000 X 1000 , then it takes 64 bits to represent one coordinate since each number takes 32 bits.int - Bits are the low level binary representation of numbers / characters in any Computer. Java uses 2's complement to represent signed numbers (positive and negative numbers).
how it works?
-
Say you want to represent a positive number 3, in binary format it will be
. compute the sum of "2 raised to the power of position of bits where bit value is 1" to get the desired outcome.0011
0 + 0 + 2 1 + 2 0
= 0 + 0 + 2 + 1
= 3 - For negative numbers, we can calculate binary representation of negative numbers using
, to get 2's complement we need to apply2's complement . i.e. inverse the bits and then add a bit1's complement .'1'
For example, binary representation for +3 is0 0 1 1
Now, inverse it1 1 0 0
Add a bit11
Result will become1 1 0 1
Note: For negative numbers left most bit (also called most significant bit) is always 1 and this represents negative sign.
Below are the bitwise operators that we can operate on bits.
Bitwise OR ( | operator) Bitwise AND ( & operator) Bitwise XOR ( ^ Exclusive OR operator) Bitwise Complement ( ~ operator) Signed Right shift operator ( >> operator) Unsigned Right shift operator ( >>> operator) Left shift operator ( << operator)
Bitwise OR ( | operator)
Bitwise OR operator returns 1 if either of bits are 1 and 0 otherwise. Below table shows bitwise OR operator results on two bits X and Y.
| X | Y | Bitwise OR result |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
Bitwise AND ( & operator)
Bitwise AND operator returns 1 if both bits are 1 and 0 otherwise. Below table shows bitwise AND operator results on two bits X and Y.
| X | Y | Bitwise AND result |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
Bitwise XOR ( ^ Exclusive OR operator)
Bitwise XOR operator returns 1 if and only if one of the bit is 1 and the other bit is 0, it returns 0 otherwise. Below table shows bitwise XOR operator results on two bits X and Y.
| X | Y | Bitwise XOR result |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
Bitwise Complement ( ~ operator)
Bitwise Complement operator is an unary operator (meaning that you can apply on a single operand), it returns 1's complement result. This means it will reverse the input bits, if the input is 0 then it returns 1 and if the input is 1 then it returns 0.
For example, consider binary representation of number is
Note:
Please note that bitwise complement of any integer n- (n + 1)
For example, consider n =3, binary representation with 8 bits is
=> Binary representation of 4 is 2's
=> 1's
=> Now, add '1'
+1
__________________________
Signed Right shift operator ( >> operator)
Signed Right shift operator is an unary operator (meaning that you can apply on a single operand), it shifts one bit to the right and fills with original most significant bit (MSB) in all the bits that are left empty as a result, the reason it fills with most significant bit is to preserve the sign of the input number.
Example:
Say we have a variable a = 2a >> 1
here is how it applied right shirt operator.
- a = 0010
a >> 1- Shift bits to right by 1 position. So,
0 0 1 0 becomes0 0 1 . - Since the input is a positive number, for positive numbers most significant bit is
. So, it fills empty bits with00 - Result now will become
0 0 0 1
a = -2a >> 1- a = 1110
a >> 1- Shift bits to right by 1 position. So,
1 1 1 0 becomes1 1 1 - Since the input is a negative number, for negative numbers most significant bit is
. So, it fills empty bits with11 - Result now will become
1 1 1 1
int data type in Java has 32 bits. In the above example, to make it simple we used 4 bits, we can apply same steps on any number of input bits.
Unsigned Right shift operator ( >>> operator)
Unsigned Right shift operator is an unary operator (meaning that you can apply on a single operand), it shifts one bit to the right and fills with
0
Say we have a variable a = -2a >>> 1
- a = 1110
a >>> 1- Shift bits to right by 1 position. So,
1 1 1 0 becomes1 1 1 - Bits that are left blank will get filled with 0
- Result now will become
0 1 1 1
Main difference between signed right shift operator and unsigned right shift operator is that unsigned right shift operator ignores the sign of input number after shifting bits whereas signed right shift operator does preserve the sign of input number.
Left shift operator ( << operator)
Left shift operator is an unary operator, it shifts one bit to the left and fills with 0
Say we have a variable a = 2a << 1
here is how it applied left shirt operator.
- a = 0010
a << 1- Shift bits to left by 1 position. So,
0 0 1 0 becomes0 1 0 - Then it fills the blanks with 0
- Result now will become
0 1 0 0
Some of the usecases where left shift operator <<
-
Powers of
can be generated efficiently with left shift operator. For example if you want to generate2 we can do this231 << 3
The idea is, in binary representation each bit position is power of , for example2 , and we are shifting right most bit 1 to the left side, by doing so we are creating a power of 2 with the position of where it shifted to.1 = 0001-
If we do
1 << 10 0 0 1 =>0 0 1 0 = 2. -
If we do
1 << 20 0 0 1 =>0 1 0 0 = 4.
as2n .1 << n -
If we do
-
Similar to powers of
, we can also generate multiplication by powers of 2, for example2 , this is equivalent tosomeNumber << 3someNumber * 23 -
Efficient data storage, by using individual bits represent flags or options, left shifting is used to set specific bits within an integer or a bit field.
For example, represents 0th bit as a flag or an option, or1 << 0 represents 1st bit as a flag or an option.1 << 1
Left shift operator works in the same way for positive and negavtive numbers and there is no Unsigned left shift operator in Java <<<