2.2 Signed Magnitude versus Two's-Complement
How does the Java virtual machine encode integer values internally in binary?
Positive values are straightforward. If we imagine that Java has a primitive integer type "nybble" (half a byte) of 4-bit integer values, then the bit patterns for the values 0 through 7 are
0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111
We reserve the leftmost bit to represent the sign: 0 for positive and 1 for negative.
Now, what about the negative
C0 1000 C1 1001 C2 1010 C3 1011 C4 1100 C5 1101 C6 1110 C7 1111
But signed magnitude has two undesirable features. First, there are two zeros, positive (bit pattern 0000) and negative (bit pattern 1000). Second, we can't use the normal binary addition logic when we have negative values for example,
6 0110 C3 1011 C3 1011 C2 1010 1 0001 5 0101
Another encoding format is two's-complement. It encodes the positive values the same way as signed magnitude, with the leftmost bit as the sign. However, it forms each negative value by complementing each bit of the positive value and then adding 1. So, for example, to form the two's-complement representation of -6,
All of the negative values are encoded as
C1 1111 C2 1110 C3 1101 C4 1100 C5 1011 C6 1010 C7 1001 C8 1000
There is only a single 0, and there is room for another negative value, -8. Now, we can also use the normal binary addition logic when we have negative values and still get the correct answers:
6 0110 C3 1101 C3 1101 C2 1110 3 0011 C5 1011
The Java virtual machine uses the two's-complement format for its byte, short, int, and long values. A value of the char type does not have a sign bit all 16 bits encode zero or a positive value.