Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hexString.toInt(32) NumberFormatException

I have a 32-bit hex value that I wish to convert to an integer.

The following methods both provide the following error given the hex string C71C5E00:

java.lang.NumberFormatException: For input string: "C71C5E00"

"C71C5E00".toInt(32)
Integer.valueOf("C71C5E00", 32)

The Kotlin docs state that an Int Represents a 32-bit signed integer, so it's not that the value is too large to pack into an Int. I've tried, in vain, prepending 0x to the string.

EDIT: As per this question I've attempted:

java.lang.Integer.parseInt("C71C5E00", 32)

Unfortunately, I am still receiving the same error.

I don't often touch Android or Kotlin so forgive my ignorance.

like image 754
amitchone Avatar asked Jan 27 '23 08:01

amitchone


1 Answers

First off, you seem to have misunderstood the radix, which is the second argument in valueOf and parseInt, and the only argument with the extension function toInt. It doesn't represent the bits in the target number type, it tells the method how to convert your string by informing it of what base it's operating in. Note that there is a second problem, which I will get back to later.

Radix is the base number of the underlying number system. By default it's 10 (the 0-arg toInt() method. toInt() calls parseInt, which looks like this:

public static int parseInt(String s) throws NumberFormatException {
    return parseInt(s,10);
}

As you see, it uses radix = 10. Again, the bits of the number type isn't relevant here. Wikipedia covers it pretty well, and Java follows more or less the same system. As you see, 16 corresponds to hex. So the appropriate radix to use here is 16.

However, like I mentioned, there's a second problem. It will still crash, because the value can't be parsed. The resulting number is 3340525056, which is more than the max int value, which is 2147483647.

Which means, you can't use any of the int methods; you'll need to use Long ones.

So, for your case, this is fine:

val x = "C71C5E00".toLong(16)

Again, the radix is the number system to use, not the amount of bits in the resulting number. If it was, you'd need to use 64 for longs.

Bonus: ints and longs have a pre-determined amount of bits. By using toInt(), you're already implicitly requesting 32 bits. with a Long, you're requesting 64 bits.

like image 125
Zoe stands with Ukraine Avatar answered Jan 31 '23 09:01

Zoe stands with Ukraine