0

基本的に、小数点以下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の投稿をいくつか読みましたが、方法がわかりませんでした。

4

2 に答える 2

0

この種の計算に再帰性を使用することは良い考えですが、作成するすべてのサブコールはポインタやその他の情報をスタックに格納し、最終的にスタックをいっぱいにします。VMの深さはわかりませんが、JVMの最大ヒープまたはスタックサイズは、連続した空きメモリをどれだけ予約できるかに依存すると思います。そのため、 -Xssparameterを使用して問題を解決できます。スタック (例: java -Xss8M YourClass)。それでもうまくいかない場合、または十分なメモリを確保できない場合は、64 ビット JVMを試してみます。

それでもうまくいかない場合は、通常の良い習慣に反して、再帰性なしでこのプログラムを実行しようとします。

これが役立つことを願っています!

于 2013-03-04T09:25:18.570 に答える
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

精度を設定して、必要な小数点以下の桁数を取得します。

于 2013-03-04T09:35:03.647 に答える