将String转换为Long,没有内置库

时间:2014-09-24 07:48:28

标签: java string overflow long-integer

我编写了Java代码,将String转换为long。但是,在处理溢出问题时,我没有线索如何解决它。如果数字溢出,计算机会认为每个数字在存储中都是合法的。 如何让程序,用64位jdk,检测实数溢出是关键问题。而且我不允许使用任何内置库,例如parseLong或其他。

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;
    }

如果数据大于long.maxvalue ,则结果无法正确存储在计算机中。

如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

您最好的选择可能是在开始之前对输入和最小/最大数字进行字典比较。

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));
}

例如,使用它如下:

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");

在这里测试:http://ideone.com/HmMkJ3

请注意,代码不会检查输入是否格式正确。我建议你先做这样的检查。 (注意0-0等案例。)

答案 1 :(得分:0)

你可以做与Long#parseLong相同的事情:

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

答案 2 :(得分:0)

我不确定你想在这里实现什么。如果String大于Long.MAX_VALUE,则表示不再是Long值。

如果您的String值的范围为Long,则可以使用Long.parseLong()而不是这种方式。

如果您想拥有庞大的号码,可以轻松使用BigDecimal

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

对于您的情况,如果值大于Long.MAX_VALUE或低于Long.MIN_VALUE

,则可以抛出异常