1

Operand1 ShiftOperator Operand2

Shift Rule

  • If either of the Operand is Negative don't forget to calculate its 2's complement since Negative integers is stored in Memory using 2's complement

  • Mask Operand2 with 0x1F

Right shift 
81814621>>-12 = 78
81814621>>>-12 = 78 

OK!!



Right shift (Operand1 is NEGATIVE)
-81814621>>-12 = -79
-81814621>>>-12 = 4017

Why different?
Left shift 
21<<-12 = 22020096
-21<<-12 = -22020096 
Unlike Right shift no matter Operand1 is Positive/Negative  
only sign get changed instead value

Thanks for all of your support! now i have a better idea on it...:)

Amit Yadav
  • 32,664
  • 6
  • 42
  • 57
  • Do you understand the difference between `>>` and `>>>`? – Oliver Charlesworth Apr 12 '14 at 10:20
  • Can anyone explain it -81814621>>-12 = -79 AND -81814621>>>-12 = 4017 how it's get calculated rather than a theoretical explanation... – Amit Yadav Apr 12 '14 at 10:38
  • It gets calculated exactly as described in the JLS. Not according to what you described above. – user207421 Apr 12 '14 at 11:11
  • I find the wording "if Operand2 is Negative then compute it’s 2’s complement" highly confusing. That could be taken to mean that you negate it, which is not even close to what happens. It could also be taken to mean (what I think you mean) that you take the number and put it in two's complement representation .. but you *already have* the number in two's complement representation. – harold Apr 12 '14 at 12:48
  • "@Harold, wording "if Operand2 is Negative then compute it’s 2’s complement" I mentioned to avoid confusion say >>-5 don’t mislead that you are going to shift with 5 its -5 so if we keep in your program it internally take -5(2's complement of 5) only but when we check assuming 5 we will get different result. Same for -873>> – Amit Yadav Apr 12 '14 at 16:37

2 Answers2

3

Wherever you got that from, it's wrong. Operand2 cannot possibly be either negative or have anything at all in its leftmost five bits after masking it with 0x1F. There is nothing in the Java Language Specification about taking the twos-complement of the shift distance, or using its left-most five bits. Read what it really says. Don't rely on arbitrary sources, or just make it up.

EDIT -81814621 is 0xFFFFFFFFFB1F9BA3, -12 is 0xFFFFFFFFFFFFFFF4, bottom five bits of that is 0x14 or 20, right shift the first operand by 20 gives 0xFFFFFFFFFFFFFFB1, which is -79.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • EJP, thanks! can you do me a favour once more to convert this -81814621>>>-12 = 4017 – Amit Yadav Apr 12 '14 at 12:24
  • It would be much more benefical if you worked through it yourself. The only thing that's different from the above is the lack of sign propagation by `>>>.` – user207421 Apr 12 '14 at 12:43
  • -81814621>>>-12 = 4017 -81814621 = FB1F 9BA3 -12 = FFFF FFF4 = FFFF FF{1111}4 = last 5-bits 0x14 = 20 -81814621>>>-12 = FB1 = 4017 Thanks EJP – Amit Yadav Apr 12 '14 at 16:45
2

The "rule" about what to do with the right-hand side operator of the shift is there because the list of values of the right operand that truly make sense is very short: for ints the range is from zero to 31, inclusive; for longs, it is zero to 63.

All other values of int on the right-hand side need to be converted to a value in the specified range. The "rule" spells out the process - i.e. re-interpreting the number as positive (that's what the two's complement is about), then masking off the higher bits, keeping the last five.

In contrast, the left operand can retain its full range. The only difference that you are experiencing has to do with the difference between >> and >>>, that is, between an operator that interprets the left-hand side operand as signed for shifting, and the one that interprets it as unsigned.

The purpose behind the >>> operator is explained in this answer. In your example, when you right-shift a negative number with the two operators, the >> leaves the number negative by sigh-extending it (i.e. shifting ones on the left) while >>> makes it positive by shifting in zeros.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523