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 !!!

- Do not try and bend the spoon. That's impossible. Instead, only try to realize the truth. - What truth? - That there is no spoon!!!

You messed up in the 2's compliment: 1000 0000 0111 1111 <-- swap bits 0000 0001 <-- add 1 --------- 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.

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

Joined: May 05, 2000
Posts: 13974

posted

0

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.

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 ]

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 add 1 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