I'd like to convert string representations of integers to actual integer values. I do not know which radix/base is being used beforehand, so I cannot simply rely on methods/constructors that take the radix as an argument (like shown here). The strings may represent unsigned 64bit integers and other large numbers, so using java.lang.Integer
is not an option.
Is there a better way of doing what I'm attempting to do with code below? Are there constructors/methods available right there in java that would allow interpretation of a string as an integer literal on their own? I know Python offers to do this when the specified radix is 0
(int()).
import java.math.BigInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LexicalIntegerCoverter {
private static final Pattern pattern =
Pattern.compile("(\\+|-)?(0(x)?)?([0-9a-fA-F]+)");
private Parts getParts(String lex) { // pun was not intended
Matcher matcher = pattern.matcher(lex);
boolean lookingAt = matcher.lookingAt();
if (lookingAt) {
String sign = matcher.group(1);
int radix;
String prefix = matcher.group(2);
if ("0".equals(prefix)) {
radix = 8;
} else if ("0x".equals(prefix)) {
radix = 16;
} else {
radix = 10;
}
String numbers = matcher.group(4);
return new Parts(sign, radix, numbers);
}
throw new NumberFormatException("Unknown lexical representation");
}
public BigInteger getLexToInt(String lex) {
Parts parts = getParts(lex.trim());
return new BigInteger(parts.getNumber(), parts.getRadix());
}
public static void main(String[] args) {
String hexLex = "0xf";
String hexLexPlus = "+0xf";
String hexLexMinus = "-0xf";
String octLex = "017";
String octLexPlus = "+017";
String octLexMinus = "-017";
String decLex = "15";
String decLexPlus = "+15";
String decLexMinus = "-15";
LexicalIntegerCoverter converter = new LexicalIntegerCoverter();
System.out.println(hexLex + " = " + converter.getLexToInt(hexLex));
System.out.println(hexLexPlus + " = " + converter.getLexToInt(hexLexPlus));
System.out.println(hexLexMinus + " = " + converter.getLexToInt(hexLexMinus));
System.out.println(octLex + " = " + converter.getLexToInt(octLex));
System.out.println(octLexPlus + " = " + converter.getLexToInt(octLexPlus));
System.out.println(octLexMinus + " = " + converter.getLexToInt(octLexMinus));
System.out.println(decLex + " = " + converter.getLexToInt(decLex));
System.out.println(decLexPlus + " = " + converter.getLexToInt(decLexPlus));
System.out.println(decLexMinus + " = " + converter.getLexToInt(decLexMinus));
}
private static class Parts {
private final String sign;
private final int radix;
private final String digits;
public Parts(String sign, int radix, String digits) {
this.sign = sign;
this.radix = radix;
this.digits = digits;
}
public String getSign() {
return sign;
}
public int getRadix() {
return radix;
}
public String getDigits() {
return digits;
}
public String getNumber() {
return (sign == null ? "" : sign) + digits;
}
@Override
public String toString() {
return getNumber() + "[" + radix + "]";
}
}
}
P.S.: there's a lot of similar questions about this, where answers point to Integer.parseInt(String, int)
or BigInteger(String, int)
, but that's not the answer I'm looking for. I'd also prefer doing this without relying on third party libraries. I'm also aware of the fact that java allows integer literals to be defined in code, which is also not the answer I'm looking for (I actually need to convert strings that contain integer literals) - I would like to do what a java compiler does when it encounters such values.
Edit01
I said above that I'd prefer not using a third party library, but that doesn't mean it's not an option.