0

Can someone tell me why this code throws an Exception?

int value = 0xabcdef01;
System.out.println(value);                 // prints -1412567295
String hex = Integer.toHexString(value);
System.out.println(hex);                   // prints abcdef01
// why does this line fail?
Integer.parseInt(hex, 16);  

This code throws the following exception:

java.lang.NumberFormatException: For input string: "abcdef01"
  at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
  at java.lang.Integer.parseInt(Integer.java:583)

I'm running on Windows 7 with the following JDK

java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
cyber-monk
  • 5,470
  • 6
  • 33
  • 42

3 Answers3

1

Perhaps what you wanted was

 int num = (int) Long.parseLong(hex, 16);  

The problem is that numbers >= 0x8000_0000 are too large to store in an int

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • My understanding of low level number storage is lacking, but Java int is 32 bits and my hex value is no more than that? – cyber-monk Aug 28 '15 at 15:53
  • Also the Long parse routine converts this to a positive long value, when in fact is should be a negative int value – cyber-monk Aug 28 '15 at 15:55
  • @cyber-monk actually your number exceeds that by a significant margin, remember that integers can be negative? That means that you actually only get 31 bits for representing your positive numbers. This effectively cuts the maximum value in half. – Blake Yarbrough Aug 28 '15 at 15:56
  • @Peter, I had assumed java would take care of the sign for me and convert it into a negative int value – cyber-monk Aug 28 '15 at 15:59
1

As you are using Java 8, consider the Integer.parseUnsignedInt method:

Integer.parseUnsignedInt(hex, 16);  
Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • thanks this solves my problem, I had assumed Integer.parseInt(..., 16) would handle hex which represents a negative int value – cyber-monk Aug 28 '15 at 16:01
1

Your confusion about integer that doesn't go back to itself has to do with peculiarities of toHexString() which returns "abcdef01" rather than "-543210ff", which really represents your original integer. Run this to see:

  int value = -0x543210ff;
  assert(value == 0xabcdef01);
  assert(value == Integer.parseInt("-543210ff", 16));
Jacob Eckel
  • 1,633
  • 1
  • 13
  • 22