Integer Literals
Integer data types comprise the following primitive data types: int, long, byte, and short (p. 41).
The default data type of an integer literal is always int, but it can be specified as long by appending the suffix L (or l) to the integer value. The suffix L is often preferred because the suffix l and the digit 1 can be hard to distinguish. Without the suffix, the long literals 2020L and 0L will be interpreted as int literals. There is no direct way to specify a short or a byte literal.
In addition to the decimal number system, integer literals can be specified in the binary (base 2, digits 0–1), octal (base 8, digits 0–7), and hexadecimal (base 16, digits 0–9 and a–f) number systems. The digits a to f in the hexadecimal system correspond to decimal values 10 to 15. Binary, octal, and hexadecimal numbers are specified with 0b (or 0B), 0, and 0x (or 0X) as the base or radix prefix, respectively.
Examples of decimal, binary, octal, and hexadecimal literals are shown in Table 2.7. Note that the leading 0 (zero) digit is not the uppercase letter O. The hexadecimal digits from a to f can also be specified with the corresponding uppercase forms (A–F). Negative integers (e.g., -90) can be specified by prefixing the minus sign (-) to the magnitude of the integer regardless of the number system (e.g., -0b1011010, -0132, or -0X5a).
Table 2.7 Examples of Decimal, Binary, Octal, and Hexadecimal Literals
Representing Integers
Integer data types in Java represent signed integer values, meaning both positive and negative integer values. The values of type char can effectively be regarded as unsigned 16-bit integers.
Values of type byte are represented as shown in Table 2.8. A value of type byte requires 8 bits. With 8 bits, we can represent 28 or 256 values. Java uses two’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 (i.e., –27) to +127 (i.e., 27 – 1), inclusive.
Table 2.8 Representing Signed byte Values Using Two’s Complement
Bits in an integral value are usually numbered from right to left, starting with the least significant bit 0 (also called the rightmost bit). 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, such that the values wrap around for integers and no overflow or underflow is indicated.
Calculating Two’s Complement
Before we look at two’s complement, we need to understand one’s complement. The one’s complement of a binary integer is computed by inverting the bits in the number. Thus the one’s complement of the binary number 00101001 is 11010110. The one’s complement of a binary number N2 is denoted as ~N2. The following relations hold between a binary integer N2, its one’s complement ~N2, and its two’s complement –N2:
−N2=∼N2+10=−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 two’s complement –N2 equals 0.
Given a positive byte value, say 41, the binary representation of -41 can be found as follows:
Adding a number N2 to its two’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:
Subtraction between two integers is also computed as addition with two’s complement:
N2 – M2 = N2 + (–M2)
For example, the expression 4110 – 310 (with the correct result 3810) is computed as follows:
The previous discussion of byte values applies equally to values of other integer types: short, int, and long. These types have their values represented by two’s complement in 16, 32, and 64 bits, respectively.