7

Edit: Clarification convert any valid number encoding from a string to a number

How does one convert a string to a number, say just for integers, for all accepted integer formats, particularly the ones that throw NumberFormatException under Integer.parseInt. For example, the code

...
int i = 0xff;
System.out.println(i);
String s = "0xff";
System.out.println( Integer.parseInt(s) );
....

Will throw a NumberFormatException on the fourth line, even though the string is clearly a valid encoding for a hexadecimal integer. We can assume that we already know that the encoding is a valid number, say by checking it against a regex. It would be nice to also check for overflow (like Integer.parseInt does), but it would be okay if that has to be done as a separate step.

I could loop through every digit and manually calculate the composite, but that would pretty difficult. Is there a better way?

EDIT: a lot of people are answering this for hexidecimal, which is great, but not completely what I was asking (it's my fault, I used hexidecimal as the example). I'm wondering if there's a way to decode all valid java numbers. Long.decode is definitely great for just catching hex, but it fails on

222222L

which is a perfectly valid long. Do I have to catch for every different number format separately? I'm assuming you've used a regex to tell what category of number it is, i.e, distinguish floats, integers, etc.

10
  • 1
    Does this help? stackoverflow.com/questions/5153811/… Commented Apr 30, 2014 at 20:31
  • 1
    If you drop the 0x, you can call Integer.parseInt(s, 16). Commented Apr 30, 2014 at 20:31
  • @dg123 That does help for hex, but doesn't solve the problem in general - doesn't catch 111_111_111 or 1111111L, for example. Commented Apr 30, 2014 at 20:45
  • @Blorgbeard This also isn't a general solution. I could certainly manually check for all cases, though that does look like a good way to check for hex numbers Commented Apr 30, 2014 at 20:45
  • 1
    Don't confuse numbers with numeric literals. The latter is just syntactic sugar. Commented Apr 30, 2014 at 21:13

4 Answers 4

5

You could do

System.out.println(Integer.decode(s));
Sign up to request clarification or add additional context in comments.

3 Comments

This is 100% the way to go!
Worth noticing that this only works for an hexadecimal value that represent a positive integer. Ex: System.out.println(Integer.decode("0xfffffff4")); will throw a NumberFormatException.
This is great for just hex, but will not decode all integers. For example, 111_111_111 is a valid integer, but will throw a number format exception
5

You need to specify the base of the number you are trying to parse:

Integer.parseInt(s,16);

This will fail if you have that "0x" starting it off so you could just add a check:

if (s.startsWith("0x")) {
    s = s.substring(2);
}
Integer.parseInt(s,16);

EDIT

In response to the information that this was not a hex specific question I would recommend writing your own method to parse out all the numbers formats you like and build in on top of Integer.decode which can save you from having to handle a couple of cases.

I would say use regex or create your own methods to validate other formats:

public static int manualDecode(String s) throws NumberFormatException {

    // Match against #####L long format
    Pattern p = Pattern.compile("\\d+L");  // Matches ########L
    Matcher m = p.matcher(s);
    if (m.matches()) {
        return Integer.decode(s.substring(0,s.length()-1));
    }

    // Match against that weird underscore format
    p = Pattern.compile("(\\d{1,3})_((\\d{3})_)*?(\\d{3})"); // Matches ###_###_###_###_###
    m = p.matcher(s);
    if (m.matches()) {
        String reformattedString = "";
        char c;
        for (int i = 0; i < s.length(); i++) {
            c = s.charAt(i);
            if ( c >= '0' && c <= '9') {
                reformattedString += c;
            }
        }
        return Integer.decode(reformattedString);
    }
    // Add as many more as you wish
    throw new NumberFormatException();
}

public int parseIntExtended(String s) {
    try {
        return Integer.decode(s);
    } catch (NumberFormatException e) {
        return manualDecode(s);
    }
}

3 Comments

And remove the 0x from the String
It seems like Parseint will catch hex if you do that, but it won't catch 111_111_111, which is a valid integer literal
@en_Knight I just saw the edit you made about this not being hex specific.
0

Integer.decode should do the trick:

public class a{
    public static void main(String[] args){
        String s="0xff";
        System.out.println(Integer.decode(s));
    }
}

Comments

0

You can try using BigInteger also but sill you have to remove 0x first or replace x from 0

int val = new BigInteger("ff", 16).intValue(); // output 255

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.