Billy Bob

Greenhorn

Posts: 21

posted 12 years ago

alright... studying for the SCJP exam and my main study aid is the latest Kathy Sierra, Osbourne Certification Press book (Sun certified programmer and developer for Java 2). I've hit the bitwise operators section and i'm running into something that doesn't make a lot of sense to me so if anyone can help out i'd appreciate it.

I want to perform x >> 4 where x = -2147483648 so i'm starting with the following 1000 (followed by 28 0's). This book has the shift occuring and leading to the following binary result: 1111 1000 (followed by 24 0's) or -134217728. If i type this number into the calculator in windows (no windows cracks ) and convert to binary i get the result mentioned in the book, however if i try to convert it back to decimal i get the following number 4160749568 which is the same number that i would get if i calculated it by hand (i.e. 2^27 + 2^28 + 2^29 + 2^30 + 2^31). Now, i'm sure i'm missing some sort of rule, not to mention the fact that the preceding excedes the value limits for a 32bit int.

If anyone can tell me how come that technique works seemingly all the time until you hit a negative value and how to appropriately deal with converting negatives by hand (binary to base 10 and base 10 to binary) i'd appreciate it. I would love to know what -38 looks like in binary and what rule i'm missing so i can get past this section cause continuing to look at it is driving me nuts .

thanks for your help

I want to perform x >> 4 where x = -2147483648 so i'm starting with the following 1000 (followed by 28 0's). This book has the shift occuring and leading to the following binary result: 1111 1000 (followed by 24 0's) or -134217728. If i type this number into the calculator in windows (no windows cracks ) and convert to binary i get the result mentioned in the book, however if i try to convert it back to decimal i get the following number 4160749568 which is the same number that i would get if i calculated it by hand (i.e. 2^27 + 2^28 + 2^29 + 2^30 + 2^31). Now, i'm sure i'm missing some sort of rule, not to mention the fact that the preceding excedes the value limits for a 32bit int.

If anyone can tell me how come that technique works seemingly all the time until you hit a negative value and how to appropriately deal with converting negatives by hand (binary to base 10 and base 10 to binary) i'd appreciate it. I would love to know what -38 looks like in binary and what rule i'm missing so i can get past this section cause continuing to look at it is driving me nuts .

thanks for your help

Jeff Bosch

Ranch Hand

Posts: 805

Pete Knecht

Ranch Hand

Posts: 33

posted 12 years ago

I think I can answer at least some of your questions. It is possible to extrapolate from things said in the K&B book that you're using to get a clear procedure for figuring negative numbers by hand. For example, suppose you have the following *int* bits:

(A) 1111...1101 1010

where there's 32 bits, and the '...' all represent 1111's. You know it's a negative number b/c the leftmost bit is 1. (Right, you with me?).

Now, procedure to calculate what negative number it is:

Flip all the bits(1's to 0's, and 0's to 1's), and then add 1. Whatever number that is, just consider it negative, and your done.

So, in (A) above, flip it to get:

0000....0010 0101

What binary number is that? 37. Now add the 1 to get 38. Now add negative sign, -38. And your done. So (A) above represents -38, like you wanted to see.

Now, take the 'reverse' of the above procedure to figure out how to represent some number as a negative (rather than having negative bits from the start). (Remember you wanted to see this all manually.)

Suppose you want to know how to represent -17. Well, you know that you need some bit arrangement such that *when it's flipped, it will equal 16* (the 1 added to that will then make 17). The following will do that:

(B) 1111...1110 1111.

This bit number represents your -17. As a check, run the first procedure to calculate its value. (Again, it's a negative, so flip bits, then add one, then take the negative.)

Flipping (B) gives you:

0000...0001 0000, which is 16. Add 1 to get 17. Take negative, -17.

Remember, during this operation, the number being worked on is 'promoted' to an int, so there are some extra steps if, say, you're shifting a byte.

Example:

byte b = -13;

b = (byte)(b >> 2);

To work this through with no shortcuts, it goes:

1. Promote -13 to an int and represent it:

(C) 1111...0011 (where the '...'s are all 1's. As an exercise satisfy yourself that this represents -13 using the above procedure).

2. Perform the shift, two to the right:

1111...1100

3. Now since in the example you must *cast* this back to a byte, you lose all the bits to the left except the rightmost 8, giving:

1111 1100

4. That's a negative, right? Calculate its value. -4. So that's your answer to the shift example. b= -4.

Finally, note that in this example a manual cast was used. If you wrote:

byte b = -13;

b >>= 2;

The compiler would auto-cast for you, but the answer would be the same. See K&B, the first couple pages of Chap. 3 on this. Extrapolate from the above example and work a few using >>> and <<. Then re-look at K&B material on this and it should make sense.

Pete.

[ April 09, 2005: Message edited by: Pete Knecht ]

Originally posted by mav:

If anyone can tell me how come that technique works seemingly all the time until you hit a negative value and how to appropriately deal with converting negatives by hand (binary to base 10 and base 10 to binary) i'd appreciate it. I would love to know what -38 looks like in binary and what rule i'm missing so i can get past this section cause continuing to look at it is driving me nuts .

thanks for your help

I think I can answer at least some of your questions. It is possible to extrapolate from things said in the K&B book that you're using to get a clear procedure for figuring negative numbers by hand. For example, suppose you have the following *int* bits:

(A) 1111...1101 1010

where there's 32 bits, and the '...' all represent 1111's. You know it's a negative number b/c the leftmost bit is 1. (Right, you with me?).

Now, procedure to calculate what negative number it is:

Flip all the bits(1's to 0's, and 0's to 1's), and then add 1. Whatever number that is, just consider it negative, and your done.

So, in (A) above, flip it to get:

0000....0010 0101

What binary number is that? 37. Now add the 1 to get 38. Now add negative sign, -38. And your done. So (A) above represents -38, like you wanted to see.

Now, take the 'reverse' of the above procedure to figure out how to represent some number as a negative (rather than having negative bits from the start). (Remember you wanted to see this all manually.)

Suppose you want to know how to represent -17. Well, you know that you need some bit arrangement such that *when it's flipped, it will equal 16* (the 1 added to that will then make 17). The following will do that:

(B) 1111...1110 1111.

This bit number represents your -17. As a check, run the first procedure to calculate its value. (Again, it's a negative, so flip bits, then add one, then take the negative.)

Flipping (B) gives you:

0000...0001 0000, which is 16. Add 1 to get 17. Take negative, -17.

Remember, during this operation, the number being worked on is 'promoted' to an int, so there are some extra steps if, say, you're shifting a byte.

Example:

byte b = -13;

b = (byte)(b >> 2);

To work this through with no shortcuts, it goes:

1. Promote -13 to an int and represent it:

(C) 1111...0011 (where the '...'s are all 1's. As an exercise satisfy yourself that this represents -13 using the above procedure).

2. Perform the shift, two to the right:

1111...1100

3. Now since in the example you must *cast* this back to a byte, you lose all the bits to the left except the rightmost 8, giving:

1111 1100

4. That's a negative, right? Calculate its value. -4. So that's your answer to the shift example. b= -4.

Finally, note that in this example a manual cast was used. If you wrote:

byte b = -13;

b >>= 2;

The compiler would auto-cast for you, but the answer would be the same. See K&B, the first couple pages of Chap. 3 on this. Extrapolate from the above example and work a few using >>> and <<. Then re-look at K&B material on this and it should make sense.

Pete.

[ April 09, 2005: Message edited by: Pete Knecht ]

Barry Gaunt

Ranch Hand

Posts: 7729

posted 12 years ago

"mav", welcome to JavaRanch. Please take a look at our JavaRanch Naming Policy and change your displayed name to conform to its requirements.

Thanks,

-Barry

Thanks,

-Barry

Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch

Getting someone to think and try something out is much more useful than just telling them the answer.