Oracle Blog

Joseph D. Darcy's Oracle Weblog

Unsigned Integer Arithmetic API now in JDK 8

At long last, after due discussion and review, I've just pushed initial API support for unsigned integer arithmetic into JDK 8!
The support is implemented via static methods, primarily on java.lang.Integer and java.lang.Long, that:

Colloquially, "unsigned integer" means a 32-bit int or 64-bit long value where all the bits are interpreted as contributing to the magnitude. In the unsigned realm, the values of an integer type of a given bit-width range from 0 to 2width-1 rather than from -(2width-1) to 2width-1-1.
A feature of the two's complement encoding of Java integers is that the bitwise results for add, subtract, and multiply are the same if both inputs are interpreted as signed values or both inputs are interpretted as unsigned values.
(Other encodings like one's complement and signed magnitude don't have this properly.)
Therefore, of the basic arithmetic operations, only a separate divide method needs to be provided to operate on values interpreted as unsigned.

To avoid dealing with the overhead of boxed values and to allow reuse of the built-in arithmetic operators, the unsigned API support does not introduce new types like UnsignedInt with instance methods to perform addition, subtraction, etc. However, that lack of separate Java-level unsigned types does mean a programmer can accidentally improperly mix signed and unsigned values. However, new unsigned types aren't the only way to mitigate this hazard. For example, a naming convention of adding a trailing "U" or "_U" to variables holding unsigned values could be adopted. A more structured approach would be to add an @Unsigned annotation type to the platform and apply that annotation to variables and fields holding unsigned values. One of the extra-linguistic checkers to be enabled by JSR 308 could then analyze code for signed/unsigned correctness.

I'm glad these methods are finally in the JDK. Later in JDK 8, there may be a few more fun bit-twiddling additions, such as methods to get the high order bits of a full multiply and methods which throw exceptions on integer overflow instead of wrapping around.

It would allow standard access to these bytecode operations from JSR 292 (and reflection).

These methods could be intrinsified by JVM, like Math.* methods. In the future, bytecode instructions can be replaced, in the bytecode generated by compiler, by calls to these new methods allowing deprecating many bytecode instructions (arithmetic, logic).
This will be an interesting first step, moving Java bytecode from a code for a pico-Java processor in 1995 to a more regular and abstract code for a current JVM (useful for easy bytecode manipulation).

That is good to see. I wonder though, if the only reason for not supporting unsigned types natively by the VM is because of concerns over conversions, why not simply force people to cast and put in compiler warnings (and on their own head be it). Failing that, put them in the VM, but don't support them in Java so other languages can take advantage. I have been wanting unsigned types for *years*. At least ten years in fact - I was first to comment on it in the bug database (4504839) - sorry for the rant there!

Anyway, I would absolutely love to see this in Java. So much of my work need high performance unsigned types. I also need unsigned longs, which of course cannot be simulated very efficiently using signed types.