Chris Su
Chris Su

Reputation: 543

Convert String to Long,No built in library

I wrote Java code to convert String to long. However, when dealing with overflow problem, I don't have clues how to solve it. If a number is overflowed, computer believe every number is legal in storage. How to let program, with 64bit jdk ,detect the real number is overflowed is the key problem. And I'm not allowed to use any built-in library such as parseLong or others.

public static long strTolong(String s){
        //error checking
        if(s == null) return 0;
        s = s.trim();//remove all space character
        boolean neg = false;//judge the number is negative or positive
        int pos = 0 ; //index of string
        long result = 0;
        //check positive or negative
        if(s.charAt(pos) == '-'){
            neg = true;
            pos++;
        }else if(s.charAt(pos) == '+') pos++;

        //calculate result
        while(pos<s.length()){
            if(s.charAt(pos) >='0' && s.charAt(pos) <='9'){
                result = result*10+(s.charAt(pos) - '0');
            }else
                break;
            pos++;
        }
        if(neg) result =-result;

        //check overflow
        if(result >Long.MAX_VALUE) {
            return Long.MAX_VALUE;
        }
        if(result<Long.MIN_VALUE){
            return Long.MIN_VALUE;
        }


        return result;
    }

If data is larger than long.maxvalue, the result can't be stored in computer correctly.

How to solve this problem?

Upvotes: 1

Views: 271

Answers (3)

aioobe
aioobe

Reputation: 420921

Your best option is probably to do a lexicographical comparison between the input and the minimum/maximum numbers before you start.

static int compare(String v1, String v2) {
    boolean neg1 = v1.startsWith("-");
    boolean neg2 = v2.startsWith("-");
    return neg1 ? (neg2 ? -comparePositives(v1.substring(1),v2.substring(1)):-1)
                : (neg2 ? 1 : comparePositives(v1, v2));
}

static int comparePositives(String v1, String v2) {
    // Is one longer?
    if (v1.length() != v2.length())
        return v1.length() < v2.length() ? -1 : 1;

    // Both empty?
    if (v1.isEmpty())
        return 0;

    // First digit differs?
    if (v1.charAt(0) != v2.charAt(0))
        return v1.charAt(0) < v2.charAt(0) ? -1 : 1;

    // Recurse on rest of number
    return comparePositives(v1.substring(1), v2.substring(1));
}

Use it for instance as follows:

if (compare(s, ""+Long.MIN_VALUE) == -1)
    throw new NumberFormatException("Input too small");

if (compare(s, ""+Long.MAX_VALUE) == 1)
    throw new NumberFormatException("Input too large");

Tested here: http://ideone.com/HmMkJ3

Note that the code does not check that the input is well formed. I suggest you do such check first. (Be aware of cases like 0 and -0 etc.)

Upvotes: 1

Ruchira Gayan Ranaweera
Ruchira Gayan Ranaweera

Reputation: 35547

I am not sure what you trying to achieve here. If String is greater than Long.MAX_VALUE means that is no more a Long value.

If your String value is withing the range of Long, you can use Long.parseLong() with out this kind of hard ways.

If you want to have huge number you can use BigDecimal easily

String max = Long.MAX_VALUE+"";
System.out.println(max);
long maxL=Long.parseLong(max)+1;
System.out.println(maxL);
BigDecimal bigDecimal=new BigDecimal(max).add(new BigDecimal("1"));
System.out.println(bigDecimal); 

Out put:

9223372036854775807 // long max value
-9223372036854775808 // incorrect result in long
9223372036854775808 // BigDecimal gives you correct one

For your case you can throws an Exception if value is greater than Long.MAX_VALUE or lower than Long.MIN_VALUE

Upvotes: 0

Thilo
Thilo

Reputation: 262464

You could do the same thing that Long#parseLong would do:

 throw new NumberFormatException("too long (pun intended): "+s);

Upvotes: 0

Related Questions