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 28 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 (?27) to +127 (27?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 N2 is denoted as ~N2. The following relations hold between a binary integer N2, its 1's complement ~N2, and its 2's complement ?N2:
?N2 = ~N2 + 1
0 = ?N2 + N2
If N2 is a positive binary integer, then ?N2 denotes its negative binary value, and vice versa. The second relation states that adding a binary integer N2 to its 2's complement ?N2 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, N2: | 00101001 | 41 |
Form 1's complement, ~N2: | 11010110 | |
Add 1: | 00000001 | |
Result is 2's complement, ?N2: | 11010111 | ?41 |
Similarly, given a negative number, say -41, we can find the binary representation of 41:
Binary Representation | Decimal Value | |
---|---|---|
Given a value, N2: | 11010111 | ?41 |
Form 1's complement, ~N2: | 00101000 | |
Add 1: | 00000001 | |
Result is 2's complement, -N2: | 00101001 | 41 |
Adding a number N2 to its 2's complement ?N2 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, N2: | 00101001 | 41 |
Add 2's complement, ~N2: | 11010111 | ?41 |
Sum: | 00000000 | 0 |
Subtraction between two integers is also computed as addition with 2's complement:
N2 ? M2 = N2 + (?M2)
For example, calculating 4110 ? 310 (with the correct result 3810) is computed as follows:
Binary Representation | Decimal Value | |
---|---|---|
Given a value, N2: | 00101001 | 41 |
Add ?M2 (i.e., subtract M2): | 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.