Sponsored Link •
All Java programs are compiled into class files that contain bytecodes, the machine language of the Java virtual machine. This article takes a look at the bytecodes that implement the logical and integer arithmetic capabilities of Java.
Welcome to yet another installment of Under The Hood. This column aims to give Java developers a glimpse of the mysterious mechanisms clicking and whirring beneath their running Java programs. This month's article continues the discussion of the bytecode instruction set of the Java virtual machine (JVM). The article takes a look at integer arithmetic and logic in the JVM, and covers the bytecodes that perform logical and arithmetic operations on integers. Subsequent articles will discuss other members of the bytecode family.
The Java virtual machine offers bytecodes that perform integer arithmetic operations on ints and longs. Values of type byte, short, and char are converted to int before they take part in arithmetic operations. For each bytecode that performs arithmetic on ints, there is a corresponding bytecode that performs the same operation on longs.
All integer types supported by the JVM -- bytes, shorts, ints, and longs -- are signed two's-complement numbers. The two's-complement scheme allows both positive and negative integers to be represented. The most significant bit of a two's-complement number is its sign bit. The sign bit is one for negative numbers and zero for positive numbers and for the number zero.
The number of unique values that can be represented by the two's-complement scheme is two raised to the power of the total number of bits. For example, the short type in Java is a 16-bit signed two's-complement integer. The number of unique integers that can be represented by this scheme is 216, or 65,536. Half of the short type's range of values are used to represent zero and positive numbers; the other half of the short type's range are used to represent negative numbers. The range of negative values for a 16-bit two's-complement number is -32,768 (0x8000) to -1 (0xffff). Zero is 0x0000. The range of positive values is one (0x0001) to 32,767 (0x7fff).
Positive numbers are intuitive in that they are merely the base two representation of the number. Negative numbers can be calculated by adding the negative number to two raised to the power of the total number of bits. For example, the total number of bits in a short is 16, so the two's-complement representation of a negative number in the valid range for a short (-32,768 to -1) can be calculated by adding the negative number to 216, or 65,536. The two's-complement representation for -1 is 65,536 + (-1) or 65,535 (0xffff). The two's-complement representation for -2 is 65,536 + (-2) or 65,534 (0xfffe).
Addition is performed on two's-complement signed numbers in the same way it would be performed on unsigned binary numbers. The two numbers are added, overflow is ignored, and the result is interpreted as a signed two's-complement number. This will work as long as the result is actually within the range of valid values for the type. For example, to add 4 + (-2), just add 0x0004 and 0xfffe. The result is actually 0x10002, but because there are only 16 bits in a short, the overflow is ignored and the result becomes 0x0002.
Overflow in integer operations does not throw any exception in the JVM. The result is merely truncated to fit into the result type. For example, adding shorts 0x7fff and 1 yields 0x8000. This means that the JVM will report that 32,767 + 1 = -32,768, so long as the values being added are shorts and not ints or longs. It is up to the Java programmer to make sure that the appropriate type -- int or long -- is chosen for integer arithmetic in each situation. (If long isn't long enough, the Java programmer should invent a class that implements really long integers and the operations upon them.) Integer division by zero does throw an ArithmeticException, so the programmer should keep in mind that this exception could be thrown and catch it if necessary.
Exposed int: A Java int reveals its inner nature
The following applet lets you play around with the two's-complement format of integers in the JVM. The Max and Min buttons will give you the maximum and minimum values of the int type. By clicking "Max" followed by "++" you can increment beyond the maximum integer and see what happens. Clicking "Min" followed by "--" lets you decrement beyond the minimum integer. Both of these result in overflow, but no exceptions are thrown by the JVM.
To view the Exposed Int applet (renamed Inner Int), visit the interactive illustrations of Inside the Java Virtual Machine at: