In programming, bitwise shift operators, >>
means arithmetic right shift, >>>
means logical right shift, the differences:
>>
, it preserves the sign (positive or negative numbers) after right shift by n bit, sign extension.>>>
, it ignores the sign after right shift by n bit, zero extension.
To work with bitwise shift operators >>
and >>>
. First, we need to know how Java uses two’s complement to represent signed numbers (positive and negative).
1. Java and Two’s complement.
Java uses two’s complement to represent signed numbers (positive and negative numbers). In the below example, we will show you how to express positive and negative numbers in two’s complement.
Note
In two’s complement, the first left bit (most significant bit) represents the sign, 0 is a positive number, 1 is a negative number
1.1 For example, 2 and -2
The binary format of 2 is 0000 0010
0000 0010
The binary format of -2 (two’s complement) is 1111 1110
0000 0010 (positive 2)
1111 1101 (invert bits)
1111 1110 (add 1)
1111 1110 (-2 in binary)
1.2 Another example, 19 and -19
The binary format of 19 is 0001 0011
0001 0011
The binary format of -19 is 1110 1101
.
0001 0011 (positive 19)
1110 1100 (invert bits)
1110 1101 (add 1)
1110 1101 (-19 in binary)
2. Arithmetic Right Shift >> or Signed Extension.
The arithmetic right shift >>
or signed right shift preserves the sign (positive or negative numbers) after bits shift. This >>
operator fills all the left empty positions with the original most significant bit (the first bit on the left).

P.S Photo copied from Wikipedia.
2.1 For example, number 19 in 8 bits, and we arithmetic right shift by 2 bits 19 >> 2
.
19 = |0001 0011|
>> 2
19 >> 2 = |??00 0100|11
In the above example, the last 2 bits 11
are shifted out of the 8 bits, but what should we fill the left first two empty positions?
The answer depends on the original most significant bit (msb). In this example, the original msb is 0, and we fill in the ??
with 0.
19 = |{0=msb}001 0011|
>> 2
19 >> 2 = |??00 0100|11
19 >> 2 = |0000 0100|11
2.2 Another example, number -19 in 8 bits, and we arithmetic right shift by 2 bits -19 >> 2
.
-19 = |1110 1101|
>> 2
-19 >> 2 = |??11 1011|01
In the above example, the original msb is 1, and we fill the ??
with 11
.
-19 = |{1=msb}110 1101|
>> 2
-19 >> 2 = |??11 1011|01
-19 >> 2 = |1111 1011|01
Again, in two’s complement, the first bit on the left (msb) represents the sign, 0 is a positive number, 1 is a negative number. The concept of copy the original most significant bit (msb) to fill in the empty bit will preserve the sign after bit shift – signed extension.
Question
Q : Wait, what is the answer to -19 >> 2
?
A: The answer is 1111 1011
or -5
.
This is how two’s complement works on negative number.
1111 1011 (this is a negative number)
1111 1010 (sub 1)
0000 0101 (invert bits)
0000 0101 (1x2^0 + 1x2^2 = 5)
In two’s complement, first bit on the left, 1 means negative, and the answer is -5.
3. Logical Right Shift >>> or Zero Extension.
This >>>
logical right shift ignores the sign and fill all the left empty positions with zero.

P.S Photo copied from Wikipedia.
3.1 For example, number 19 in 8 bits, and we logical right shift by 2 bits 19 >>> 2
.
19 = |0001 0011|
>>> 2
19 >>> 2 = |??00 0100|11
19 = |0001 0011|
>>> 2
19 >>> 2 = |0000 0100|11
3.2 For negative number -19, it is the same. No matter what condition, the logical right shift will fill left empty positions with zero, ignore the sign.
-19 = |1110 1101|
>>> 2
-19 >>> 2 = |??11 1011|01
-19 = |1110 1101|
>>> 2
-19 >>> 2 = |0011 1011|01
Question
Q: Wait, again, what is the answer of -19 >>> 2
?
For 8 bits. The answer is 59.
0011 1011 (positive number)
0011 1011 (1x2^0) + (1x2^1) + (1x2^3) + (1x2^4) + (1x2^5)
0011 1011 (1 + 2 + 8 + 16 + 32) = 59
In Java, integer, 32 bits, 4 bytes. The answer is 1073741819.
System.out.println(-19>>>2); // 1073741819
In Java, -19
, convert it to binary.
Input -19 = 11111111|11111111|11111111|11101101
-19 >> 2 = 11111111|11111111|11111111|11111011 = -5
-19 >>> 2 = 00111111|11111111|11111111|11111011 = 1073741819
Any use cases for these bitwise operator >>> or >>? Please comments, thanks.
Note
If you found any errors or typo, specially in the binary format, do comment and let me know 🙂
4. Java Print Integer in Binary format.
This is the Java program to use Integer.toBinaryString
print an Integer
in Binary format.
ByteSign.java
package com.favtuts.crypto.bytes; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class ByteSign { public static final String OUTPUT_FORMAT = "%32s"; public static void main(String[] args) { String STRING_FORMAT = "%-10s = %s"; int number = 24; System.out.println("Positive Number"); System.out.println(String.format(STRING_FORMAT, "Input " + number, printBinary(number))); System.out.println(String.format(STRING_FORMAT, number + " >> 2", printBinary(number >> 2))); System.out.println(String.format(STRING_FORMAT, number + " >>> 2", printBinary(number >>> 2))); int number2 = -19; System.out.println("\nNegative Number"); System.out.println(String.format(STRING_FORMAT, "Input " + number2, printBinary(number2))); System.out.println(String.format(STRING_FORMAT, number2 + " >> 2", printBinary(number2 >> 2))); System.out.println(String.format(STRING_FORMAT, number2 + " >>> 2", printBinary(number2 >>> 2))); } public static String printBinary(int number) { return printBinary(number, 8, "|"); } public static String printBinary(int number, int blockSize, String separator) { // pad leading zero String pBinary = String .format(OUTPUT_FORMAT, Integer.toBinaryString(number)) .replace(" ", "0"); // split by blockSize List<String> result = new ArrayList<>(); int index = 0; while (index < pBinary.length()) { result.add(pBinary.substring(index, Math.min(index + blockSize, pBinary.length()))); index += blockSize; } return result.stream().collect(Collectors.joining(separator)); } }
Output
Positive Number
Input 24 = 00000000|00000000|00000000|00011000
24 >> 2 = 00000000|00000000|00000000|00000110
24 >>> 2 = 00000000|00000000|00000000|00000110
Negative Number
Input -19 = 11111111|11111111|11111111|11101101
-19 >> 2 = 11111111|11111111|11111111|11111011
-19 >>> 2 = 00111111|11111111|11111111|11111011
Download Source Code
$ git clone https://github.com/favtuts/java-core-tutorials-examples
$ cd java-crypto