Programmer Programmer - 1 year ago 68
Java Question

Convert String representation to minimal Number Object

Having a String representation of a number(no decimals), what's the best way to convert it to either one of

? The only condition is that the converted type should be of minimal datatype required to hold the number.

I've this current implementation that works fine, but I would like to know if there's a better code without exception handling.

package com.stackoverflow.programmer;

import java.math.BigInteger;

public class Test {
public static void main(String[] args) {

String number = "-12121111111111111";
Number numberObject = null;
try {
numberObject = Integer.valueOf(number);
} catch (NumberFormatException nfe) {
System.out.println("Number will not fit into Integer type. Trying Long...");
try {
numberObject = Long.valueOf(number);
} catch (NumberFormatException nfeb) {
System.out.println("Number will not fit into Long type. Trying BigInteger...");
numberObject = new BigInteger(number);
System.out.println(numberObject.getClass() + " : "
+ numberObject.toString());

Answer Source

From what you said, here is what I would have done:

import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;

public class TestSO09_39463168_StringToMinimalNumber {

    public static void main(String[] args) {
        List<String> strNumbers = Arrays.asList("0", //int
                "123", //int
                "-456", //int
                "2147483700", // Long
                "-2147483700", // Long
                "9223372036854775900", //BigInt
                "-9223372036854775900" //BigInt

        for(String strNumber : strNumbers){
            Number number = stringToMinimalNumber(strNumber);
            System.out.println("The string '"+strNumber+"' is a "+number.getClass());


    public static Number stringToMinimalNumber(String s){
        BigInteger tempNumber = new BigInteger(s);

        if(tempNumber.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0 || tempNumber.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0){
            return tempNumber;
        } else if(tempNumber.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0 || tempNumber.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0){
            return tempNumber.longValue(); //Autobox to Long
        } else {
            return tempNumber.intValue(); //Autobox to Integer



You must use a temporary BigInteger, or else you'll end up with lazarov's solution, which is correct, but you can't really do something like that for reason mentionned in the comments.

Anyway, every BigInteger (the ones that are not returned) will be garbage collected. As for autoboxing, I don't think it's that of a bad thing. You could also make "BigInteger.valueOf(Long.MAX_VALUE))" as a constant. Maybe the compiler or the JVM will do this on its own.

I'm not really sure of how efficient it is, and using only BigInteger might be a good idea (as Spotted did), because I serioulsy doubt it would really improve the rest of your code to use the right size, and it might even be error prone if you try to use these Numbers with each other ... But again, it all depend on what you need. (and yes, using Exception as flow control is a really bad idea, but you can add a try catch on the BigInteger tempNumber = new BigInteger(s); to throw your own exception if s is not a number at all)

For recreational purpose, I have made the solution without using a BigInteger, and only with String parsing (this is still not what I recommand to do, but it was fun :)

public static final String INT_MAX_VALUE = "2147483647";
public static final String LONG_MAX_VALUE = "9223372036854775807";

public static Number stringToMinimalNumberWithoutBigInteger(String numberStr){
    //Removing the minus sign to test the value
    String s = (numberStr.startsWith("-") ? numberStr.substring(1,numberStr.length()) : numberStr);

    if(compareStringNumber(s, LONG_MAX_VALUE) > 0){
        return new BigInteger(numberStr);
    } else if(compareStringNumber(s, INT_MAX_VALUE) > 0){
        return new Long(numberStr);
    } else {
        return new Integer(numberStr);

//return postive if a > b, negative if a < b, 0 if equals;
private static int compareStringNumber(String a, String b){
    if(a.length() != b.length()){
        return a.length() - b.length();
    for(int i = 0; i < a.length(); i++){
        if( a.codePointAt(i) != b.codePointAt(i) ){ //Or charAt()
            return a.codePointAt(i) - b.codePointAt(i);
    return 0;