Musings on JDK development

  • Java
    January 20, 2012

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:

  • Provide bidirectional conversion between strings and unsigned integers
  • Compare values as unsigned
  • Compute unsigned divide and remainder

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.

Join the discussion

Comments ( 13 )
  • guest Saturday, January 21, 2012

    At the same time, could you add bytecode instructions for arithmetic and logic, as methods to the classes representing primitives, like that:

    // in class java.lang.Integer, add new methods like that:

    public final int add(int first, int second) {

    return first + second;


    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).



  • Stephen Colebourne Saturday, January 21, 2012

    The exception throwing maths methods would be useful for JSR-310, given the current "temporary" MathUtils class:


  • Adam Malter Saturday, January 21, 2012

    Thanks so much Joe!

    This is going to be a huge help when dealing with data over the wire and re-implementing algorithms from C.

    Any word on if the HotSpot guys will plug in intrinsics for these, or is that something that only gets done after profiling (or specJbb) shows it useful?

  • Kieron Wilkinson Sunday, January 22, 2012

    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.

    Step in the right direction anyway!

  • Joe Darcy Wednesday, January 25, 2012

    @Adam and @Kieron,

    I don't know of any plans by Oracle's HotSpot team to add intrinsics for the new unsigned operations, but I for one would welcome that vein of contributions by external community members!

  • guest Thursday, January 26, 2012

    Guava has it already. :)

  • guest Monday, January 30, 2012

    Nice! How about support for unsigned byte so we don't need to & 0xFF

  • guest Monday, February 20, 2012

    What about unsigned literals? Will the following compile on JDK 8?

    int i = 3000000000;

  • Joe Darcy Monday, February 20, 2012


    While unsigned literals were for a time on the feature list of Project Coin for JDK 7, they are not currently planned for JDK 8.

  • chase Thursday, March 22, 2012

    Correct me if I am wrong, but doesn't java HAVE a reserved unsigned keyword already? Wouldn't that be easier to use then an annotation?

  • Joe Darcy Tuesday, March 27, 2012


    No, the Java programming language does not have an unsigned keyword; the list of keywords are given in the JLS:


  • Jabberwo Wednesday, May 23, 2018
    Integer class's parseInt and valueOf of the Integer class both throw NumberFormatException if the string literal contains a number above MAX_VALUE.

    int test1 = Integer.parseInt( "2147483648" );
  • Joe Darcy Thursday, August 9, 2018

    Use Integer.parseUnsignedInt.
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.