17

I'm without my Java reference book and I'm having a tough time finding an answer with Google.

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

int value = 0x0100;

int result = (value >> 8);
System.out.println("(value >> 8) = " + result);  // Prints: "(value >> 8) = 1"

result = (value >>> 8);
System.out.println("(value >>> 8) = " + result); // Prints: "(value >>> 8) = 1"
Nate
  • 18,892
  • 27
  • 70
  • 93
  • 1
    Possible duplicates: [Difference between >>> and >>](http://stackoverflow.com/q/2811319/1529630), [Difference between >>> and >> operators](http://stackoverflow.com/q/1972356/1529630) – Oriol Mar 29 '16 at 19:53

9 Answers9

23

Signed integers use the high-order bit to denote sign.

So >> preserves the sign, while >>> doesn't. This is why >> is referred to as the arithmetic shift and >>> is the logical shift.

This way, you can do (assuming 32-bit integers) the following:

  • -10 >> 1 yields -5 (0xFFFFFFF6 >> 1 yields 0xFFFFFFFB - notice the high-order bit stays the same.)
  • -10 >>> 1 yields 2147483643 (0xFFFFFFF6 >>> 1 yields 0x7FFFFFFB - notice all of the bits were shifted, so the high-order bit is now zero. The number is no longer negative according to twos-complement arithemetic.)

For positive integers, >> and >>> act the same, since the high-order bit is already zero.

It also explains why there is no need for a <<< operator. Since the sign would be trashed by sliding the bits to the left, it would map to no reasonable arithmetic operation.

lavinio
  • 23,931
  • 5
  • 55
  • 71
  • @BillK Although the answer is good, but haven't you seen that when you are going to comment, SO asks you not to write things like **+1** or **thanks** ? – dryairship Jan 06 '16 at 12:48
  • @PriydarshiSingh I wouldn't normally but I thought it was useful to point out that this should be voted up above the accepted answer (seems to have worked). Would it have been better if I just said "Most useful answer"? Also, are you absolutely certain that guideline existed in '09? – Bill K Jan 06 '16 at 17:06
19

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

  • 0xDEADBEEF >>> 80x00DEADBE (logical shift, the one you want)
  • 0xDEADBEEF >> 80xFFDEADBE (arithmetic shift)
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
Budric
  • 3,599
  • 8
  • 35
  • 38
9

From Java Notes: Bitwise Operators:

n >> p (right shift) Shifts the bits of n right p positions. If n is a 2's complement signed number, the sign bit is shifted into the high-order positions.

Example: 5 >> 2 = 1

n >>> p (right shift) Shifts the bits of n right p positions. Zeros are shifted into the high-order positions.

Example: -4 >>> 28 = 15

William Brendel
  • 31,712
  • 14
  • 72
  • 77
7

For positive numbers, there is no difference. Negative (two's complement) numbers will be filled with zeros for >>> and ones for >>.

1010 0110 >>>2 = 0010 1001

1010 0110 >> 2 = 1110 1001

dhackner
  • 2,942
  • 2
  • 20
  • 23
5

The correct answer has been posted more than once, but not from an authoritative source.

This is from the JLS §15.19 Shift Operators:

The shift operators include left shift <<, signed right shift >>, and unsigned right shift >>>; they are syntactically left-associative (they group left-to-right). The left-hand operand of a shift operator is the value to be shifted; the right-hand operand specifies the shift distance.

...

The value of n>>s is n right-shifted s bit positions with sign-extension. The resulting value is ⌊n/2s⌋. For nonnegative values of n, this is equivalent to truncating integer division, as computed by the integer division operator /, by two to the power s.

The value of n>>>s is n right-shifted s bit positions with zero-extension. If n is positive, then the result is the same as that of n>>s; if n is negative, the result is equal to that of the expression (n>>s)+(2<<~s) if the type of the left-hand operand is int, and to the result of the expression (n>>s)+(2L<<~s) if the type of the left-hand operand is long. The added term (2<<~s) or (2L<<~s) cancels out the propagated sign bit. (Note that, because of the implicit masking of the right-hand operand of a shift operator, ~s as a shift distance is equivalent to 31-s when shifting an int value and to 63-s when shifting a long value.)

Community
  • 1
  • 1
Michael Myers
  • 188,989
  • 46
  • 291
  • 292
  • 1
    Thanks a lot for this reply. It answers a different question I had: How to effectively perform an arithmetic shift on a CPU that has only logical shifts. "(n>>s)+(2<<~s)" seems a good answer to that :-) – Mecki Dec 08 '10 at 09:57
2

The >> is an arithmetic shift, which preserves the sign bit in any 'vacant' bits. The other is a logical shift which fills the vacant spots with zeroes.

James
  • 2,050
  • 13
  • 15
1

The arithmetic shift >> is division by two for signed integers, while the logical shift >>> is division by two for unsigned numbers (if you interpret the bit pattern in a signed Java int as an unsigned integer).

starblue
  • 55,348
  • 14
  • 97
  • 151
0

some info

the >> operator preserves the leftmost bits. The leftmost bits are filled with the previous content. This is to do with sign extension. In this case there is a 1 at the left and it is preserved. If you do not want to keep the 1 to the left, use the >>> operator which shifts 0's into the leftmost bits

akf
  • 38,619
  • 8
  • 86
  • 96
0

It has to do with signed value math. The >>> pills in zeros for the hight order bits, the >> preservers the sign bit and pulls it in.

BCS
  • 75,627
  • 68
  • 187
  • 294