The code snippet
char tell = 'A';
System.out.println("The new valeu is "+(~tell));
The crash
Do not compile and run it yet. Read it again, compile it mentally and keep the output in your mind (I doubt you can guess it).
If you already know the outcome and you are able to explain it, perhaps you should just leave this post, otherwise, you are about to crash, then, get ready.
The output of that snippet is: The new value is -66. I didn’t bold it cause I wanted you to read it all and pay attention and not just CTRL + find it . Now, you can stop reading here, go back to the snippet, take a breath and think a bit. Why would that code result in such outcome? If you find out the reasons for such outcome, then, you don’t need me to reboot you, otherwise, keep reading.
The reboot
Let’s destile down that code snippet. We have two lines of code. The first one declares a character variable and assigns it the letter A. Remember that the char type in Java corresponds to a 16 bits Unicode character. The A character is on the position 65 (decimal) of the Unicode table. We will need this information soon. Let’s move to the second line of code, straight to the end of it. What does the operator ~ do? It basically shifts the bits order of the operand. This clearly means that the operand has to be an integral type. That’s why the compiler will automatically consider the decimal value of the tell variable. This means that we will have the following: ~65.
What’s the result of this expression then?
To get to that we have to convert this decimal number to binary and then shift the bits.
The decimal representation of 65 is 01000001. This means that now we have ~01000001.
Applying the bits shift operator we get: ~01000001 = 10111110.
Bla Bla Bla. This still not explain why the result is a negative number in first place. So what? Are you playing me Mario? No, I’m not. Let me finish.
The Java language uses the two’s complement technique no represent negative values in binary.
This technique establishes that:
Every binary sequence where the leftmost bit is 0, is considered positive or unsigned.
Every binary sequence where the leftmost bit is 1, is considered negative.
Now, if you pay a little more attention, you will notice that our resulting bits sequence represents a negative number: 10111110. Seems like you are now getting answers.
You might be tempted to believe that this binary sequence represents the decimal value 66. But you are not wrong. if you copy it and past on any online converter from binary to decimal, you will get the value 190. Go ahead test it by yourself. Try http://www.binaryhexconverter.com/binary-to-decimal-converter.
Assuming that you have already faced the reality, let me guess your spiritual state: What’s going on here? Why isn’t it 66?
Well, the reason is simple: if we want to convert a two’s complement negative binary sequence back to decimal, we have to shift it first and then add 1 bit to it, then we are good to go.
What we are going to do is: shift it first and then add 1 bit to it. Ok, let’s do it.
We have: 10111110.
Shifting: ~10111110 = 01000001
Adding one bit: 01000001+1 = 01000010
Result: 01000010
What we just did is explained by the two’s complement formula :
~x + 1 = -x
~10111110 + 1 = -01000010
Now we can convert the 01000010 binary sequence to decimal: copy the it and go back to
http://www.binaryhexconverter.com/binary-to-decimal-converter . The result, as expected, will be 66, so, you just have to add the sign on the left. The final result will be -66.
It’s weird isn’t it? Two simple lines of code required all this knowledge in order to decipher their outcome.
Now that I have rebooted you, it’s time for you to share this post with your friends and watch them crash.
It is always a pleasure. Happy Monday.


Comentários Recentes