465

What is the difference between >>> and >> operators in Java?

Teocci
  • 7,189
  • 1
  • 50
  • 48
Vipul
  • 4,675
  • 3
  • 16
  • 3
  • 2
    Possible duplicates: [Java's >> versus >>> Operator?](http://stackoverflow.com/q/1034640/1529630), [Difference between >>> and >> operators](http://stackoverflow.com/q/1972356/1529630) – Oriol Mar 29 '16 at 19:54

9 Answers9

507

>> is arithmetic shift right, >>> is logical shift right.

In an arithmetic shift, the sign bit is extended to preserve the signedness of the number.

For example: -2 represented in 8 bits would be 11111110 (because the most significant bit has negative weight). Shifting it right one bit using arithmetic shift would give you 11111111, or -1. Logical right shift, however, does not care that the value could possibly represent a signed number; it simply moves everything to the right and fills in from the left with 0s. Shifting our -2 right one bit using logical shift would give 01111111.

Ziggy
  • 21,845
  • 28
  • 75
  • 104
danben
  • 80,905
  • 18
  • 123
  • 145
  • 13
    While I agree and appreciate that arithmetic shifts _can_ be used to multiply signed numbers by `2^k`, I find it weird that this is everyone's answer. A string of bits isn't a number, and `>>` can always be used on any string of bits: it always does the same thing regardless of the role that string of bits is playing and regardless of whether it has a concept of 'sign'. Would it be OK to extend your already great answer with a discussion of the case when your operand is _not_ being interpreted as a signed number? Does my complaint makes sense? – Ziggy Nov 22 '14 at 17:57
  • 14
    Why do you say a string of bits isn't a number? Would you say a sequence of decimal digits isn't a number? – danben Dec 09 '14 at 00:51
  • 6
    @danben Discussing whether it is or isn't a number only makes sense if you link it to a context. If the internet is just electricity, then I agree that a String is just a number. – bvdb Aug 17 '15 at 10:30
  • 1
    @danben but actually, I think what Ziggy was really refering to (imho), is that a `String` could also be regarded as a `char[]`. He's not saying that a `char` is not a number ; he's just saying that it's an **unsigned** number. I think that's where he's lost. – bvdb Aug 17 '15 at 10:33
  • 12
    @Ziggy is right: Not every string of bits is a number, and not every sequence of decimal digits is a number. For example: Telephone numbers, post codes (in many countries) etc. are strings of decimal digits, but it doesn't make sense to add, subtract or multiply them, so they're not really numbers. They happen to be strings of decimal digits, but should be treated as strings of characters. (Post codes in Canada and UK contain letters and digits.) – jcsahnwaldt Reinstate Monica Dec 15 '17 at 02:00
  • 1
    While the answer and explanation are correct I think it could be improved. Consider that System.out.println((byte) -2 >> 1) outputs -1 (binary 8 bit 1111111) and not 127 (binary 8 bit 01111111) as casual reader of the example might conclude. While it is true that 8 bit -2 is 11111110 it gets promoted to int i.e. 11111111111111111111111111111110 when the >>> operator is applied. I Think if the example would use 32 bits it would be clearer. – nyholku Oct 04 '18 at 10:34
  • Aware that I'm late to the game but what am I missing here. Why are there so many 1 bits in 2? Isn't -2 represented in 8 bits 01000000 and 2 01000001? – Ari Black Jun 08 '22 at 15:39
  • Be aware that the differentiation of `>>` and `>>>` only makes sense in the context of interpreting it as signed number or not. Because in one case a zero is shifted in on the left, in the other case the MSB is copied. There is no instruction to shift in a 1, which could be an option for bare bit sequences as well. – Queeg Jun 13 '22 at 14:57
119

>>> is unsigned-shift; it'll insert 0. >> is signed, and will extend the sign bit.

JLS 15.19 Shift Operators

The shift operators include left shift <<, signed right shift >>, and unsigned right shift >>>.

The value of n>>s is n right-shifted s bit positions with sign-extension.

The value of n>>>s is n right-shifted s bit positions with zero-extension.

    System.out.println(Integer.toBinaryString(-1));
    // prints "11111111111111111111111111111111"
    System.out.println(Integer.toBinaryString(-1 >> 16));
    // prints "11111111111111111111111111111111"
    System.out.println(Integer.toBinaryString(-1 >>> 16));
    // prints "1111111111111111"

To make things more clear adding positive counterpart

System.out.println(Integer.toBinaryString(121));
// prints "1111001"
System.out.println(Integer.toBinaryString(121 >> 1));
// prints "111100"
System.out.println(Integer.toBinaryString(121 >>> 1));
// prints "111100"

Since it is positive both signed and unsigned shifts will add 0 to left most bit.

Related questions

Community
  • 1
  • 1
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
55

>>> will always put a 0 in the left most bit, while >> will put a 1 or a 0 depending on what the sign of it is.

corsiKa
  • 81,495
  • 25
  • 153
  • 204
54

They are both right-shift, but >>> is unsigned

From the documentation:

The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension.

Matt
  • 43,482
  • 6
  • 101
  • 102
  • 14
    can you explain with an example – Kasun Siyambalapitiya Sep 04 '16 at 05:22
  • 1
    I also think you should give an example. – byxor Dec 06 '16 at 12:25
  • I suppose that `>>>` is unsigned, but why does `7>>32=7`? I ran a loop that did one shift at a time and saw that after `32` shifts, it came back to `7`. The only way that this could make sense is that for each number shifted out, it entered an "outer circle." After `32` shifts, it reached somehow back to it's position, but obviously that still doesn't make sense. What is going on? – Ian L Mar 30 '17 at 02:39
  • @IanLimarta It doesn't? I just get 0. (`for (int i = 7 << 1, j = 0; j < 32; j++) System.out.println(Integer.toString(i >>= 1, 2));`) If you mean why `>>32` itself returns the original value, see [this](http://stackoverflow.com/questions/3170412/why-is-132-1). – Salem Mar 31 '17 at 15:47
  • I'm sorry. I meant why does '7>>>32=7'. – Ian L Mar 31 '17 at 17:21
  • @IanLimarta When I ran some tests on this, what I found is that when using the logical shift right ">>>", if you're right shifting a positive number, the result will continue to be a positive number, so it doesn't behave any differently than the arithmetic right shift ">>". If you're using the logical shift right ">>>" on a negative number, then that's when it makes a difference because the left-most bits brought in are zeros. Yet with the example you asked about, doing a logical shift right 32 bits is going to return the same starting value you're trying to shift anyway. – Hoonerbean Jul 03 '17 at 01:13
46

The logical right shift (v >>> n) returns a value in which the bits in v have been shifted to the right by n bit positions, and 0's are shifted in from the left side. Consider shifting 8-bit values, written in binary:

01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000

If we interpret the bits as an unsigned nonnegative integer, the logical right shift has the effect of dividing the number by the corresponding power of 2. However, if the number is in two's-complement representation, logical right shift does not correctly divide negative numbers. For example, the second right shift above shifts 128 to 32 when the bits are interpreted as unsigned numbers. But it shifts -128 to 32 when, as is typical in Java, the bits are interpreted in two's complement.

Therefore, if you are shifting in order to divide by a power of two, you want the arithmetic right shift (v >> n). It returns a value in which the bits in v have been shifted to the right by n bit positions, and copies of the leftmost bit of v are shifted in from the left side:

01111111 >> 2 = 00011111
10000000 >> 2 = 11100000

When the bits are a number in two's-complement representation, arithmetic right shift has the effect of dividing by a power of two. This works because the leftmost bit is the sign bit. Dividing by a power of two must keep the sign the same.

andru
  • 589
  • 4
  • 6
15

Read more about Bitwise and Bit Shift Operators

>>      Signed right shift
>>>     Unsigned right shift

The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator >>> shifts a zero into the leftmost position,

while the leftmost position after >> depends on sign extension.

In simple words >>> always shifts a zero into the leftmost position whereas >> shifts based on sign of the number i.e. 1 for negative number and 0 for positive number.


For example try with negative as well as positive numbers.

int c = -153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.println(Integer.toBinaryString(c <<= 2));

System.out.println();

c = 153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));

output:

11111111111111111111111111011001
11111111111111111111111101100100
  111111111111111111111111011001
11111111111111111111111101100100

                          100110
                        10011000
                          100110
                        10011000
Braj
  • 46,415
  • 5
  • 60
  • 76
  • Thanks. Just want to add a comment to reference the bit representation for **Integer.MAX_VALUE, Integer.MIN_VALUE, -1, 0, 1**. eg: `System.out.println(Integer.MAX_VALUE + ": " + String.format("%32s", Integer.toBinaryString(Integer.MAX_VALUE)).replace(' ', '0'))`; **Integer.MAX_VALUE**: `01111111111111111111111111111111;` **Integer.MIN_VALUE**: `10000000000000000000000000000000;` **-1**: `11111111111111111111111111111111;` **0**: `00000000000000000000000000000000;` **1**: `00000000000000000000000000000001` – Andy Dong Aug 22 '18 at 06:15
7

The right shift logical operator (>>> N) shifts bits to the right by N positions, discarding the sign bit and padding the N left-most bits with 0's. For example:

-1 (in 32-bit): 11111111111111111111111111111111

after a >>> 1 operation becomes:

2147483647: 01111111111111111111111111111111

The right shift arithmetic operator (>> N) also shifts bits to the right by N positions, but preserves the sign bit and pads the N left-most bits with 1's. For example:

-2 (in 32-bit): 11111111111111111111111111111110

after a >> 1 operation becomes:

-1: 11111111111111111111111111111111
solimant
  • 809
  • 9
  • 15
2
>>  Signed right shift 
>>> Unsigned right shift

Example:-

byte x, y;  x=10;  y=-10;  
SOP("Bitwise Left Shift: x<<2 = "+(x<<2));  
SOP("Bitwise Right Shift: x>>2 = "+(x>>2));  
SOP("Bitwise Zero Fill Right Shift: x>>>2 = "+(x>>>2));  
SOP("Bitwise Zero Fill Right Shift: y>>>2 = "+(y>>>2));

output would be :-

Bitwise Left Shift: x<<2 = 40
Bitwise Right Shift: x>>2 = 2
Bitwise Zero Fill Right Shift: x>>>2 = 2
Bitwise Zero Fill Right Shift: y>>>2 = 1073741821
Procrastinator
  • 2,526
  • 30
  • 27
  • 36
-2

>>(signed) will give u different result for 8 >> 2, -8 >> 2.

right shift of 8

8 = 1000 (In Binary)

perform 2 bit right shift

8 >> 2:

1000 >> 2 = 0010 (equivalent to 2)

right shift of -8

8 = 1000 (In Binary)

1's complement = 0111

2's complement:

0111 + 1 = 1000

Signed bit = 1

perform 2 bit right shift (on 2's co result)

8 >> 2:

1000 >> 2 = 1110 (equivalent to -2)


>>(unsigned) will give u same result for 8 >>> 2, -8 >>> 2.

unsigned right shift of 8

8 = 1000

8 >>> 2 = 0010

unsigned right shift of -8

-8 = 1000

-8 >>> 2 = 0010

neha
  • 62
  • 5