# i don't get shift operators!!!!

Vicken Karaoghlanian
Ranch Hand
Posts: 522
i don't understand the following senario for the shift operator:

the result of this code is -128, i'll try to explain it, if i am wrong please correct me:
1) 1 is coverted to binary ---> 0000 0001
2) 1 << 7 ---> 1000 0000
3) now java thinks that the number is negative.
4) to convert a -ve number to it's decimal value we transfer it to it's 2nd complement and add 1
5) 2nd comp ---> 1111 1111
6) adding one (the part i don't get)---> 0 !!!

Thomas Paul
mister krabs
Ranch Hand
Posts: 13974
You messed up in the 2's compliment:
1000 0000
0111 1111 <-- swap bits
---------
1000 0000 <-- result
That number is -128. A byte can not hold +128 which is why after 2's compliment you end up back where you started.

Vicken Karaoghlanian
Ranch Hand
Posts: 522
how do you explain this

the output is always 15 and not 0!!!
however when applying x >>> 8 or 16, it'll result 0 !!!
i am confused.

Thomas Paul
mister krabs
Ranch Hand
Posts: 13974
A shift is always done by doing a mod on the number of bits to shift with the number of bits of the object to shift. You have to remember that before shifting, the variable will be promoted to an int.
That means that
myint>>>32 is actually myint>>>32%32 which is actually myint>>>0
myint>>>65 is actually myint>>>65%32 which is actually myint>>>1
So any shifting with a multiple of 32 will do nothing.

Leslie Chaim
Ranch Hand
Posts: 336
See the Cat c Mouse games :roll:
Though there are some corrections which I think should be made. First of all the 2's compliment is missing The images are OK but the wording and logic flow is hard to follow.
Particularly somwhare two thirds in the article it says ..

So result = -99 >> 2;
looks like this:

Should really be:

So result = -99 >> 2;
The operand -99

[ July 29, 2003: Message edited by: Leslie Chaim ]

Ross Goldberg
Ranch Hand
Posts: 63
In case it isn't clear, I just want to add to Thomas' explanation that int is 32 bits...since all bitshift operations are promoted to ints (for the operators (or numbers), that is), the MAXIMUM number of shifts would be 31 (like he said, 32 mod 32 (32 % 32 in Java) = 0 (the remainder is 0).
Remember the signed and unsigned shifting!!!
if you shift x >> 2 (I hope I don't get this backwards!), the sign goes along and you get this for x = 15:
0000 0000 0000 0000 0000 0000 0000 1111
becomes
0000 0000 0000 0000 0000 0000 0000 0011 (note all the numbers shift 2 to the right and thus two "1" symbols fall off.
So 15 >> 2 = 3
But for x = -15, you have this representation
First...to reverse, you'll be flipping the bit representation of 15 - 1 (since to get the value of a negative number, you flip all bits and add 1...so I'm doing the reverse to create -15)
14 is
0000 0000 0000 0000 0000 0000 0000 1110
(so if you had flipped bits and added 1, it would end in 1111 which = 15)
Now, flip the bits to get the representation of -15 as stored in the int variable:
1111 1111 1111 1111 1111 1111 1111 0001
When you shift -15 >> 2, that is a signed shift...so the 1 bit stays a 1 bit even though you are shifting right...the net result is that bits keep being added to the left while those on the right may drop off...the first shift results in:
1111 1111 1111 1111 1111 1111 1111 1000 (note everything shifted right, but then the leftmost bit was turned back into a 1)
The second shift becomes
1111 1111 1111 1111 1111 1111 1111 1100
Now reverse it:
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0100
And -15 >> 2 = 4
Now throw the sign back on: -4
That's two's complement...somewhat confusing, but once you understand the basic formula of flip, add 1, put the negative sign back in, it isn't so bad.
Now....there is also the unsigned RIGHT shift (no left one as that leftmost bit would fall off and thus becomes irrelevant)....the difference is that instead of the sign bit being turned back on if negative after a shift, in this case, the sign bit is not turned back on and you have a shift that looks the same as it would for a positive number.
Therefore, with x = 15:
0000 0000 0000 0000 0000 0000 0000 1111
you get 3 again (ends in 0011)
but with x = -15:
1111 1111 1111 1111 1111 1111 1111 0001
you get
0011 1111 1111 1111 1111 1111 1111 1100
Note that this becomes a very big POSITIVE number of 1073741820 (thus, unsigned)....but there is one case where an unsigned shift does NOT become positive...
if it is shifted by a multiple of 32 digits, nothing happens (remember the x % 32 = 0?).
BTW, I learned nearly all of this from Head First Java...if you can afford at least a 1 week detour, this book is well worth it for the incredibly solid foundation it lays. Actually, now that I think about it, it may have been in the cert book, but I'm fairly certain it was in the HFJ. Both are must-reads, IMHO.
Ross

 It is sorta covered in the JavaRanch Style Guide.