大输入的java.lang.StackOverflowError异常

时间:2013-03-04 09:16:21

标签: java string recursion stack overflow

基本上,我正在编写一个程序来手动进行简单的除法,我希望小数位达到10 ^ 6个位置。该程序适用于输入< 3000,但当我走高时,它显示: Exception in thread "main" java.lang.StackOverflowError

这是我的代码:

{
....
....
int N=100000;//nth place after decimal point
String res=obj.compute(N,103993.0,33102.0,ans); //division of 103993.0 by 33102.0
System.out.println(res);
}

public String compute (int n, double a, double b, String ans){
        int x1=(int)a/(int)b;
        double x2=a-x1*b;
        double x3=x2*10;
        int c=0;
        if (n==0||n<0)
            return ("3."+ans.substring(1));
        else if (x3>b){
            ans+=""+x1;
            c=1;
        }
        else if(x3*10>b){
            ans+=x1+"0";
            c=10;
        }
        else if(x3*100>b){
            ans+=x1+"00";
            c=100;
        }
        else if(x3*1000>b){
            ans+=x1+"000";
            c=1000;
        }
        else if(x3*10000>b){
            ans+=x1+"0000";
            c=10000;
        }
        return compute(n-String.valueOf(c).length(),x3*c,b,ans);
    }

我不是Java的任何核心程序员。我需要帮助来解决这种情况。我读了一些关于增加堆栈大小的SO帖子,但我不明白这个方法。

2 个答案:

答案 0 :(得分:0)

使用递归来进行这种计算是一个好主意,但是你做的每个子调用都会将指针和其他信息存储在堆栈中,最终填充它。我不知道VM的深度,但我认为JVM的最大堆或堆栈大小取决于可以保留多少连续的可用内存,因此可以通过使用 -Xssparameter 解决您的问题,这会改变堆栈的大小(例如java -Xss8M YourClass)。如果这仍然不起作用或者您无法获得内存,我会尝试使用 64位JVM

如果所有这些都不起作用,与通常的良好做法相反,我会尝试执行此程序没有递归

我希望这有帮助!

答案 1 :(得分:0)

从compute()到compute的递归调用导致堆栈溢出。改变你的方法来使用循环而不是递归,它会扩展得更好。有关您可以使用的不同划分算法,请参阅维基百科页面:https://en.wikipedia.org/wiki/Division_%28digital%29

或者像这样使用BigDecimal:

public class Main {
    public static void main(String... args) {
        final int precision = 20;
        MathContext mc = new MathContext(precision, RoundingMode.HALF_UP);
        BigDecimal bd = new BigDecimal("103993.0");
        BigDecimal d = new BigDecimal("33102.0");
        BigDecimal r = bd.divide(d, mc);
        System.out.println(r.toString());
    }
}

输出:3.1415926530119026041

设置精度以获得所需的小数位数。