Caused by: java.lang.NumberFormatException: For input string: "ffffe75f01499c00"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Long.parseLong(Long.java:415)
at java.lang.Long.valueOf(Long.java:491)
This is EXPECTED as ffffe75f01499c00 (in hex) is much more than the max limit of the long which is 9,223,372,036,854,775,807 (in decimal)
I am not able to figure how the first function "valueToString" would return a string "ffffe75f01499c00" ...there is no processing except for storing the value in Database and then reading it back again and converting back to long using "stringToValue" ...
I think the question is more "how did something start as a long, and after what is theoretically a round trip no longer fits into a long".
The obvious question to be is, what was the original value of valLong? Then, what was the original result of Long.toString(valLong,16)? It shouldn't be hard to track down where the weirdness is happening, and that might give clues to what is causing it.
I've got a guess as to what's happening, but I'm still not sure why it's happening.
Those leading Fs look suspicious. Could the initial value be negative? My guess is that it's getting confused between signed and unsigned representations of the number. Read the documentation for Long.toString(val, 16) and Long.toHexString() - they feel like they ought to be the same but they treat negative numbers differently. However, my brief reading of the documentation would suggest that toString ought to give you the behaviour you want, whereas toHexString might give the problem you're seeing. But I could be wrong. I'd suggest experimenting with some negative inputs and see what happens.
It may be because integer literals are all unsigned. If you write them in decimal, for an byte for example, you are allowed 0..2147483648, but there are restrictions on the use of 2147483648. I see the new edition of the Java™ Language Specification is now available online But you see the limits for literals in hex or binary would be 0x0..0xffff_ffff or 0b0..0b1111_1111_1111_1111_1111_1111_1111_1111. So the range of hex/decimal literals is double that of decimal literals. So you can get a hex value in unsigned > 0x7fff_ffff from Integer.toHexString(). Now, you see that parseInt has restrictions on its arguments.
I think they have contrived a situation where the range of strings which can be used as an integer literal is different from the range of Strings accepted by parseInt.
I haven’t checked about Longs, but suspect the same occurs there.
Matthew Brown wrote:I've got a guess as to what's happening, but I'm still not sure why it's happening.
Those leading Fs look suspicious. Could the initial value be negative? My guess is that it's getting confused between signed and unsigned representations of the number. Read the documentation for Long.toString(val, 16) and Long.toHexString() - they feel like they ought to be the same but they treat negative numbers differently. However, my brief reading of the documentation would suggest that toString ought to give you the behaviour you want, whereas toHexString might give the problem you're seeing. But I could be wrong. I'd suggest experimenting with some negative inputs and see what happens.
I think you're on to something. That String contains 16 characters. Each represents 16 bits so the total is 64 bits. In other words, a full long.
The maximum value of a long is 7fffffffffffffff. ffffe75f01499c00 is "larger" than that, and is therefore negative. Basically, any 16-char String that does not start with 7 or below is negative. You can't use Long.parseLong on these Strings. You would need to do the parsing manually. A quick attempt without validation:
I found something else out when testing though. Long.toHexString(valLong) will return "ffffe75f01499c00". However, for the same long, Long.toString(valLong, 16) will return "-18a0feb66400". If you switch to that method you should have no problem parsing the Strings back into longs.
Rob Spoor wrote:
I found something else out when testing though. Long.toHexString(valLong) will return "ffffe75f01499c00". However, for the same long, Long.toString(valLong, 16) will return "-18a0feb66400". If you switch to that method you should have no problem parsing the Strings back into longs.
Right. The toString(val, radix) and parse(string, radix) complement each other, but do not deal in twos complement.
Rob Spoor wrote:
I found something else out when testing though. Long.toHexString(valLong) will return "ffffe75f01499c00". However, for the same long, Long.toString(valLong, 16) will return "-18a0feb66400". If you switch to that method you should have no problem parsing the Strings back into longs.
Oh, good! Because I didn't test it, but that's what I interpreted the documentation to say.
Which does mean the behaviour doesn't seem to be quite matching the code posted, unfortunately.
You're right about that. I checked it with both Java 6 and Java 7 and both return different values for Long.toString and Long.toHexString. I've also checked the source code of Java 1.4 and it too returns different values (toHexString calls toUnsignedString).
Post by:autobot
Think of how dumb the average person is. Mathematically, half of them are EVEN DUMBER. Smart tiny ad:
a bit of art, as a gift, the permaculture playing cards