Integer data types in Java represent signed integer values, that is, both positive and negative integer values. The values of char type can effectively be regarded as unsigned 16-bit integers.
Values of type byte are represented as shown in Table G.2. A value of type byte requires 8 bits. With 8 bits, we can represent 2^{8} or 256 values. Java uses 2's complement (explained later) to store signed values of integer data types. For the byte data type, this means values are in the range ?128 (?2^{7}) to +127 (2^{7}?1), inclusive.
Bits in an integral value are usually numbered from right to left, starting with the least significant bit 0 (also called the right-most bit). When applying bitwise operators, the number of the most significant bit (also called the left-most bit) is dependent on the integral type; bit 31 for byte, short, char, and int, and bit 63 for long. The representation of the signed types sets the most significant bit to 1, indicating negative values. Adding 1 to the maximum int value 2147483647 results in the minimum value -2147483648, that is, the values wrap around for integers and no overflow or underflow is indicated.
Decimal Value | Binary Representation (8 bit) | Octal Value with Prefix 0 | Hexadecimal Value with Prefix 0x |
---|---|---|---|
127 | 01111111 | 0177 | 0x7f |
126 | 01111110 | 0176 | 0x7e |
... | ... | ... | ... |
41 | 00101001 | 0123 | 0x29 |
... | ... | ... | ... |
2 | 00000010 | 02 | 0x02 |
1 | 00000001 | 01 | 0x01 |
0 | 00000000 | 00 | 0x0 |
-1 | 11111111 | 0377 | 0xff |
-2 | 11111110 | 0376 | 0xfe |
... | ... | ... | ... |
-41 | 11010111 | 0327 | 0xd7 |
... | ... | ... | ... |
?127 | 10000001 | 0201 | 0x81 |
?128 | 10000000 | 0200 | 0x80 |
Before we look at 2's complement, we need to understand 1's complement. 1's complement of a binary integer is computed by inverting the bits in the number. Thus, 1's complement of the binary number 00101001 is 11010110. 1's complement of a binary number N_{2} is denoted as ~N_{2}. The following relations hold between a binary integer N_{2}, its 1's complement ~N_{2}, and its 2's complement ?N_{2}:
?N_{2} = ~N_{2} + 1
0 = ?N_{2} + N_{2}
If N_{2} is a positive binary integer, then ?N_{2} denotes its negative binary value, and vice versa. The second relation states that adding a binary integer N_{2} to its 2's complement ?N_{2} equals 0.
Given a positive byte value, say 41, the binary representation of -41 can be found as follows:
Binary Representation | Decimal Value | |
---|---|---|
Given a value, N_{2}: | 00101001 | 41 |
Form 1's complement, ~N_{2}: | 11010110 | |
Add 1: | 00000001 | |
Result is 2's complement, ?N_{2}: | 11010111 | ?41 |
Similarly, given a negative number, say -41, we can find the binary representation of 41:
Binary Representation | Decimal Value | |
---|---|---|
Given a value, N_{2}: | 11010111 | ?41 |
Form 1's complement, ~N_{2}: | 00101000 | |
Add 1: | 00000001 | |
Result is 2's complement, -N_{2}: | 00101001 | 41 |
Adding a number N_{2} to its 2's complement ?N_{2} gives 0, and the carry bit from the addition of the most significant bits (after any necessary extension of the operands) is ignored:
Binary representation | Decimal value | |
---|---|---|
Given a value, N_{2}: | 00101001 | 41 |
Add 2's complement, ~N_{2}: | 11010111 | ?41 |
Sum: | 00000000 | 0 |
Subtraction between two integers is also computed as addition with 2's complement:
N_{2} ? M_{2} = N_{2} + (?M_{2})
For example, calculating 41_{10} ? 3_{10} (with the correct result 38_{10}) is computed as follows:
Binary Representation | Decimal Value | |
---|---|---|
Given a value, N_{2}: | 00101001 | 41 |
Add ?M_{2} (i.e., subtract M_{2}): | 11111101 | ?3 |
Result: | 00100110 | 38 |
The previous discussion on byte values applies equally to values of other integer types: short, int, and long. These types have their values represented by 2's complement in 16, 32, and 64 bits, respectively.