Vicken Karaoghlanian

Ranch Hand

Posts: 522

posted 14 years ago

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

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

Thomas Paul

mister krabs

Ranch Hand

Ranch Hand

Posts: 13974

posted 14 years ago

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.

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.

Associate Instructor - Hofstra University

Amazon Top 750 reviewer - Blog - Unresolved References - Book Review Blog

Vicken Karaoghlanian

Ranch Hand

Posts: 522

Thomas Paul

mister krabs

Ranch Hand

Ranch Hand

Posts: 13974

posted 14 years ago

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.

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.

Amazon Top 750 reviewer - Blog - Unresolved References - Book Review Blog

Leslie Chaim

Ranch Hand

Posts: 336

posted 14 years ago

See the Cat c Mouse games :roll:

Though there are some corrections which I

Particularly somwhare two thirds in the article it says ..

Should really be:

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

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;

Theoperand -99

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

Normal is in the eye of the beholder

Ross Goldberg

Ranch Hand

Posts: 63

posted 14 years ago

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

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