1. Bitwise left shift
Java also has 3 bitwise shift operators: If you really need to, you can very simply shift all the bits of a number several positions to the left or right.
To shift the bits of a number to the left, you need the bitwise left shift operator. This is how it's written:
a << b
Where a
is the number whose bits are being shifted, and b
is a number that indicates how many times to shift the bits of the number a
to the left. During this operation, the loworder bits added on the right are zeros.
Examples:
Example  Result 









Shifting one digit to the left has the same effect as multiplying a number by 2.
Want to multiply a number by 16? 16 is the same as 2^{4}. So you shift the number 4 digits to the left
2. Bitwise shift right
Bits can also be shifted to the right. To do this, use the bitwise right shift operator. This is how it's written:
a >> b
Where a
is the number whose bits are being shifted, and b
is the number of times to shift the bits of the number a
to right.
Examples:
Example  Result 









Shifting one digit to the right has the same effect as dividing a number by 2.
During this operation, the highorder bits added on the left are zeros, but not always!
The leftmost bit of a signed number is called the sign bit: if the number is positive, it is 0
; but if the number is negative, this bit is 1
.
When shifting the bits of a number to the right, the value of the sign bit would ordinarily also shift and the sign of the number would be lost. Accordingly, for negative numbers (where the leftmost bit is 1
), this bit gets special treatment. When shifting the bits of a number to the right, a 0
is added on the left if the leftmost bit was 0
, and a 1
is added on the left if the leftmost bit was 1
.
But in the example above, that doesn't appear to be the result. Why? Because integer literals are int
s, and 0b11111111
actually means 0b00000000000000000000000011111111
. That is, the leftmost bit is zero.
Many programmers are frustrated by this rightshift behavior and would prefer the number to always be padded with zeros. So Java added another right shift operator.
This is how it's written:
a >>> b
Where a
is the number whose bits are being shifted, and b
is the number of times to shift the bits of the number a
to right. This operator always appends zeros on the left, regardless of the original value of the sign bit of the number a
.
3. Working with flags
Programmers created an almost entirely new field of study on the basis of bitwise and shift operations: working with flags.
When computers had very little memory, it was highly popular to cram a lot of information into a single number. A number was treated as an array of bits: an int is 32 bits, and a long is 64 bits.
You can write a lot of information in such a number, especially if you need to store logical (true
or false
) values. A single long
is like a boolean
array comprised of 64 elements. These bits were called flags and were manipulated using the following operations:

set flag(make a specific bit equal to
1
) 
reset flag(make a specific bit equal to
0
) 
check flag(check the value of a specific bit)
And here's how it's done with bitwise operators.
Setting a flag
To set a specific bit to 1
, you need to perform a bitwise OR operation between the number whose bit you want to set and a specially created number, where only that bit is 1
.
For example, suppose you have the number 0b00001010
and you need to set the 5th bit to 1
. In that case, you need to:
0b00001010  0b00010000 = 0b00011010
If the 5th bit had been set to one already, then nothing would have changed.
In general, the operation of setting a flag can be written as follows
a  (1 << b)
Where a
is the number whose bit will be set to 1
. And b
is the position of the bit to be set. Using the left shift operator is super convenient here, since you can immediately tell which bit we are working with.
Resetting a flag
To reset a specific bit (i.e. set it to 0
) without disturbing other bits, you need to perform an &
operation between the number whose bit you want to reset (i.e. set to 0
) and a specially created number, where all the bits are equal to 1
except for the bit you want to reset.
For example, suppose you have the number 0b00001010
and you need to set the 4th bit to 0
. In that case, you need to:
0b00001010 & 0b11110111 = 0b00000010
If the 4th bit had been set to zero already, then nothing would have changed.
In general, the operation of resetting a flag can be written as follows
a & ~(1 << b)
Where a
is the number whose bit will be reset to 0
. And b
is the position of the bit to be cleared.
To get a number where all the bits are 1
except the one we want to be zero, we first shift 1 b positions to the left, and then use the bitwise NOT
operator to invert the result.
Checking a flag
In addition to setting or resetting a specific flag, sometimes you just need to check whether a given flag is set, i.e. whether a certain bit is equal to 1
. This is quite easy to do with a bitwise &
.
For example, suppose you need to check whether the 4th bit is set to 1
in the number 0b00001010
. Then you need to do this:
if ( (0b00001010 & 0b00001000) == 0b00001000 )
In general, the operation of checking a flag can be written as follows
(a & (1 << b)) == (1 << b)
Where a
is the number whose bit is being checked. And b
is the position of the bit to be checked.
4. Encryption
The bitwise XOR
operation is often used by programmers for simple encryption. In general, such encryption looks like this:
result = number ^ password;
Where number
is the data we want to encrypt, password
is a special number used as a "password" for the data, and result
is the encrypted number.
number == (number ^ password) ^ password;
The important thing here is that when the XOR
operator is applied to a number twice, it produces the original number, regardless of the "password".
To recover number
from the encrypted result
, you just need to perform the operation again:
original number = result ^ password;
Example:
class Solution
{
public static int[] encrypt(int[] data, int password)
{
int[] result = new int[data.length];
for (int i = 0; i < data.length; i++)
result[i] = data[i] ^ password;
return result;
}
public static void main(String[] args)
{
int[] data = {1, 3, 5, 7, 9, 11};
int password = 199;
// Encrypt the array of data
int[] encrypted = encrypt(data, password);
System.out.println(Arrays.toString(encrypted));
// Decrypt the array of data
int[] decrypted = encrypt(encrypted, password);
System.out.println(Arrays.toString(decrypted));
}
}
GO TO FULL VERSION