Archive for March 11th, 2009

Java Frustration : Parsing Integers

Recently, when I was working with jhammer, I discovered a frustrating ‘feature’ of some of the default Java Integer and Long methods.  I hope to save some other coders the same trouble.  The problem comes down to this:

Integer.parseInt(Integer.toHexString(i),16) != i;

When the integer i has the most significant bit set (i.e. 0×80000000) , parseInt will throw a NumberFormatException.  I don’t think this is a problem with the methods or their implementation, but rather is a result of Java’s lack of support for ‘unsigned’ integers.  i.e. – a 32 bit integer is ranged from -0×40000000 to 0×40000000, with the upper-most bit being the ’sign’ bit.  This would be okay, except for the Integer.toHexString method returns a (hexidecimal) string that represents an unsigned 32-bit integer: The string form of 0xa0000000 (decimal -1610612736, in 2’s compliment) is represented as “0xa0000000″, which is unparsable by Integer.parseInt as it is not (really) a ‘valid’ signed 32-bit integer.

There are two solutions that I came up with:

  1. Roll your own solution (which is what I did, as it looks better to the user, in my opinion).
  2. Test the upper-most bit and flip the ’signs’ of the outputted hexadecimal string.  It looks something like this:
String prefix = ((value & 1<<31) != 0) ? "-" : "";
String value_str = prefix + Integer.toHexString(-value);

This will create out parsable hexadecimal numbers that will be ‘correct’ 31-bit integers.  The same process can be followed to create parsable hexadecimal Longs.