Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java negative int to hex and back fails

public class Main3 {
    public static void main(String[] args) {
        Integer min = Integer.MIN_VALUE;
        String minHex = Integer.toHexString(Integer.MIN_VALUE);

        System.out.println(min + " " + minHex);
        System.out.println(Integer.parseInt(minHex, 16));
    }
}

Gives

-2147483648 80000000
Exception in thread "main" java.lang.NumberFormatException: For input string: "80000000"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Integer.parseInt(Integer.java:459)
    at Main3.main(Main3.java:7)

Whats up?

like image 335
Maxim Veksler Avatar asked May 10 '09 12:05

Maxim Veksler


People also ask

Can you have a negative int in Java?

A number of the "int" type in Java can range from -2,147,483,648 up to 2,147,483,647.

How do you parse a negative value in Java?

String binary = Integer. toBinaryString(-1); // convert -1 to binary // 11111111 11111111 11111111 11111111 (two's complement) int number = Integer. parseInt(binary, 2); // convert negative binary back to integer System.

How can I convert a hex string to an integer value?

To convert a hexadecimal string to an integer, pass the string as a first argument into Python's built-in int() function. Use base=16 as a second argument of the int() function to specify that the given string is a hex number.


1 Answers

This is something that's always annoyed me. If you initialize an int with a hex literal, you can use the full range of positive values up to 0xFFFFFF; anything larger than 0x7FFFFF will really be a negative value. This is very handy for bit masking and other operations where you only care about the locations of the bits, not their meanings.

But if you use Integer.parseInt() to convert a string to an integer, anything larger than "0x7FFFFFFF" is treated as an error. There's probably a good reason why they did it that way, but it's still frustrating.

The simplest workaround is to use Long.parseLong() instead, then cast the result to int.

int n = (int)Long.parseLong(s, 16);

Of course, you should only do that if you're sure the number is going to be in the range Integer.MIN_VALUE..Integer.MAX_VALUE.

like image 112
Alan Moore Avatar answered Sep 18 '22 15:09

Alan Moore