views:

1405

answers:

4

While writing a game for J2ME we ran into an issue using java.lang.Integer.parseInt()

We have several constant values defined as hex values, for example:

CHARACTER_RED = 0xFFAAA005;

During the game the value is serialized and is received through a network connection, coming in as a string representation of the hex value. In order to parse it back to an int we unsuccesfully tried the following:

// Response contains the value "ffAAA005" for "characterId"
string hexValue = response.get("characterId");
// The following throws a NumberFormatException
int value = Integer.parseInt(hexValue, 16);

Then I ran some tests and tried this:

string hexValue = Integer.toHexString(0xFFAAA005);
// The following throws a NumberFormatException
int value = Integer.parseInt(hexValue, 16);

This is the exception from the actual code:

java.lang.NumberFormatException: ffaaa005
    at java.lang.Integer.parseInt(Integer.java:462)
    at net.triadgames.acertijo.GameMIDlet.startMIDlet(GameMIDlet.java:109)

This I must admit, baffled me. Looking at the parseInt code the NumberFormatException seems to be thrown when the number being parsed "crosses" the "negative/positive boundary" (perhaps someone can edit in the right jargon for this?).

Is this the expected behavior for the Integer.parseInt function? In the end I had to write my own hex string parsing function, and I was quite displeased with the provided implementation.

In other words, was my expectation of having Integer.parseInt() work on the hex string representation of an integer misguided?

EDIT: In my initial posting I wrote 0xFFFAAA005 instead of 0xFFAAA005. I've since corrected that mistake.

+6  A: 

The String you are parsing is too large to fit in an int. In Java, an int is a signed, 32-bit data type. Your string requires at least 36 bits.


Your (positive) value is still too large to fit in a signed 32-bit int.

erickson
My mistake when writing the question, the behavior still happens with 0xFFaaa005 which is the value that we are using in the code.
Esteban Brenes
http://bugs.sun.com/view_bug.do?bug_id=4068580
kdgregory
"If you parse a negative value, it will work: "-FFAAA005"", no that does not work either. That will also overflow for a signed 32-bit int.
Esteban Brenes
kdgregory: thanks, that answers my question.
Esteban Brenes
+1  A: 

I'm not a java dev, but I'd guess parseInt only works with integers. 0xFFFAAA005 has 9 hex digits, so it's a long, not an int. My guess is it's complaining because you asked it to parse a number that's bigger than it's result data type.

Jonathan
Thanks, fixed it in the question. The actual code value is 0xFFAAA005, not the 0xFFFAAA005 I originally listed in the question.
Esteban Brenes
+2  A: 

Do realize that your input (4289372165) overflows the maximum size of an int (2147483647)?

Try parsing the value as a long and trim the leading "0x" off the string before you parse it:

public class Program {
    public static void main(String[] args) {
     String input = "0xFFFAAA005";
     long value = Long.parseLong(input.substring(2), 16);
     System.out.print(value);
    }
}
Andrew Hare
Please look at the edited version. Thanks for pointing out that mistake in my original posting of the question.
Esteban Brenes
Your input (even after being corrected) is still too big for an int.
Andrew Hare
A: 

Your number seems to be too large to fit in an int, try using Long.parseLong() instead. Also, the string doesn't seem to get parsed if you have 0x in your string, so try to cut that off.

Jorn
Thanks. I've since corrected that, the problem of writing things from memory instead of looking at the actual code.
Esteban Brenes