aspose file tools*
The moose likes Java in General and the fly likes Bitwise Unary NOT Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Bitwise Unary NOT" Watch "Bitwise Unary NOT" New topic
Author

Bitwise Unary NOT

Tejas Kansara
Ranch Hand

Joined: Dec 14, 2000
Posts: 38
Could anyone please explain me the following :
How come the output of ~3 is -4
Could you give me a brief explaination regarding the same.
And few hints related to Left/Right Shift,etc
I am preparing for SCJP and in ref. books I am not having enough of explaination.
Thanking you in ANTICIPATION.
Regards
Tejas
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
I think the Java 2 Certification Passport has an excellent explanation of the subject, if you can wait for its publishing date. But then again, I'm not impartial: half the 'ranch crowd has contributed to this book, and I did the technical review.
To understand these operations, you need to understand binary:
0101 = (0 * 2^3) + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 5
Negative numbers use 2's complement: you flip all the bits (a not operation), then add one.
-5 = -( 0101 ) = 1010 + 1 = 1011
Why this weird convention? Simple: this way, a number added to its negation works out to be zero using the normal bitwise addition rules:
0101
1011
----+
0000
Of course, that is exactly what a negative number is supposed to do. So apparently 2's complement is the right representation for a negative number under bitwise addition. (I'll leave it up to the reader to show the same for multiplication, and to see what happens if you do the same for the 8-bit representation of -5 instead of the 4-bit one shown above).
Now you can understand why ~n = -n-1 for all n! It's the way negative numbers are constructed in 2's complement.
Bitshifts are easy.
0101 >> 1 = 0010 = 2 = 5/2 (you lose the least significant bit)
0010 << 1 = 0100 = 4 = 2*2<br /> But watch out!<br /> 1011 >> 1 = 1101 = -3 = (-5)/2 (always rounding down, and a "1" is shifted into the left to preserve sign)
1011 >>>1 = 0101 = 5 (the unsigned bitshift operator always shifts in "0" and does not preserve sign)
0101 << 1 = 1010 = -6 (the left shift operator overflows in this case - there is no signed 4-bit representation of 5*2=10)
- Peter

[This message has been edited by Peter den Haan (edited October 20, 2001).]
Tejas Kansara
Ranch Hand

Joined: Dec 14, 2000
Posts: 38
Thanx Peter but still doubts :
---------------------------------------------------------------
0101 >> 1 = 0010 = 2 = 5/2
0010 << 1 = 0100 = 4 = 2*2<br /> What does 5/2 and 2*2 suggests ??? - Explain pleazeee ...<br /> A N D..... the one below : <br /> 1011 >> 1 = 1101 = -3 = (-5)/2 (always rounding down, and a "1" is shifted into the left to preserve sign)
1011 >>>1 = 0101 = 5 (the unsigned bitshift operator always shifts in "0" and does not preserve sign)
0101 << 1 = 1010 = -6 (the left shift operator overflows in this case - there is no signed 4-bit representation of 5*2=10)<br /> I AM CONFUSED WITH THE NEGATIVE SHIFTS <br /> i.e <br /> 1011 >> 1 is how come -3 ....
1011 >>> 1 is how come 5 ....
DO ME A FAVOR AND CLEAR MY DOUBTS
THANX AGAIN.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
0101 >> 1 = 0010 = 2 = 5/2
0101 = 5. 0010 = 2. Right shift by one is equivalent to integer division by 2.
0010 << 1 = 0100 = 4 = 2*2<br /> 0010 = 2. 0100 = 4. Left shift by one is equivalent to multiplication by 2.<br /> The >>> unsigned right shift operator always shifts in zeroes from the left, which means that negative numbers are turned into positive numbers - the leftmost (most significant) bit is the sign bit, always 1 for negative numbers. Just work out a few examples and you'll see the logic.
The >> signed right shift operator is equivalent to integer division, for negative numbers as well as positive numbers, so right-shifting -5 gives (-5)/2 = -3.
I know this feels inadequate, but at this stage nothing beats taking pencil and paper and trying things out. If you have any specific problems please post.
- Peter
Jane Griscti
Ranch Hand

Joined: Aug 30, 2000
Posts: 3141
Hi Tejas,
There are some notes and alternate links on the different number systems and two's-complement arithmetic here. They are not as succint as Peter's explanation but they may help.
Peter, thanks for the book plug
------------------
Jane Griscti
Sun Certified Programmer for the Java� 2 Platform


Jane Griscti
SCJP, Co-author Mike Meyers' Java 2 Certification Passport
Tejas Kansara
Ranch Hand

Joined: Dec 14, 2000
Posts: 38
Peter thanks for all your co-operation and help
actually I have been working on bitwise topic since
few days. Actually to some extent I am clear with few
operators but when it comes to negative values, I get confused.
Also explain how to judge a negative value when it is written in binary form.
My main problem is with NEGATIVE VALUES AND SHIFTS. Mainly negative shifts.
Guide me pleazzzzz.
Just see to the following program and explain the output b'coz it gives a vast difference
when it is 5 and -5
class RightShift
{
public static void main(String[] args)
{
int i =-5;
//int i = 5;
i >>= 1;

System.out.println(i);
}
}
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
To get the decimal value of a negative binary value: just invert the 2-s complement procedure! Subtract one (using normal binary subtraction), invert all the bits, then determine the value as usual.
Negative shifts. In terms of values, they are extremely easy to understand: a negative shift by 1 means the value gets divided by 2 and rounded down. In terms of bit patterns, it isn't very difficult either: the whole pattern gets shifted to the right, leftmost (sign) bit determines the value of the new bit shifted in from the left. The difficult part is probably to understand that these two viewpoints are equivalent. I can post an algebraic proof, if you want; but would that be useful to you? (The core of the proof is the observation that the unary NOT and the signed bitshift operators commute, i.e. (~n) >> 1 = ~(n >> 1)).
- Peter
Tejas Kansara
Ranch Hand

Joined: Dec 14, 2000
Posts: 38
Peter could you please explain the following :
int i =-31;
How will you convert the -31 to binary and back again to decimal.
Please do me a favor. I am just CONFUSED with negative values.
One more interesting topic
double a,b;
Thanx.....
a = 2.0;
b = 0.0;
double c = a/b;
Now when I do the following why it gives different results.
int x = (int) c;
and
byte y = (byte) c;
Waiting for reply.
Manish Hatwalne
Ranch Hand

Joined: Sep 22, 2001
Posts: 2578

Originally posted by Tejas Kansara:
Please do me a favor. I am just CONFUSED with negative values.

Have a look at this, and see if it is of any help.
HTH,
- Manish
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
I don't think there's anything I could add to Manish' excellent explanation.
Regarding the second issue,
Originally posted by Tejas Kansara:
double a,b;
a = 2.0;
b = 0.0;
double c = a/b;
Now when I do the following why it gives different results.
int x = (int) c;
and
byte y = (byte) c;
This is due to a peculiarity of the Java language - when converting numbers to short or byte, it actually performs this conversion in two steps, first converting to an int and then casting this to a short or byte. The last step merely throws away the extraneous bits.
First, the value of c is Double.POSITIVE_INFINITY (after all, you're dividing by zero).
There is no direct representation of this "number" as an integer, so in "(int) c" it is converted to its closest equivalent, Integer.MAX_VALUE, the largest value a variable of type int will hold. This (2147483647) is the value you get when you print x.
The expression "(byte) c" does not directly convert c to a byte; instead, it first converts c to an int, then casts the int to a byte. You could just as well replace it by "(byte) x". The bit pattern of Integer.MAX_VALUE is 01111111111111111111111111111111. Chop off the first 24 bits to give an 8-bit byte and you end up with 11111111, which works out to be -1. That is the value printed when you print y.
- Peter
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Bitwise Unary NOT