2016-10-17 18 views
0

を投げ、私は自分のコードを実行しようとすると、私はエラーによってjava.lang.StackOverflowErrorを得る:再帰関数がjava.lang.StackOverflowErrorを

public class calc { 
    public static void main(String[] args){ 
double zahl = 847362; 
System.out.println(wannawoerk(zahl)); 

} 


public static double wannawoerk(double zahl){ 
    if (zahl == 1) 
     return 1; 
    else 
     return wannawoerk(zahl - 1) + zahl; 
} } 

は、この問題の任意の回避策はありますか?私はのためにせずに再帰関数を使用する必要があり、一方で、など

+3

なぜ 'double'ですか?ここで問題となるのは、A)スタックが847,361フレームの深さになることはできません(それについて考える、それは大変です)か、B)IEEE-754倍精度バイナリ浮動小数点のゲームとゲームです。私は(A)と思われますが、 –

+0

"アプリケーションの再帰が深すぎるためにスタックオーバーフローが発生した場合にスローされます。" – eldo

答えて

0

再帰を使用する必要がある場合は、スタックに使用可能なメモリを増やすことができます。java -Xss256m YourClass - スタックを最大256MBに設定します。

現実世界では、おそらくwhileループを使用しています。または、この場合はすぐに計算してください(コンピューティングしているものを再帰する必要はありません)が、それは重要ではないと思います。

+1

あなたのクローズドフォームソリューションはあまり正しくありません。 – Bathsheba

+0

@Bathshebaあなたは正しいです。私はそれが二次的で問題の点ではないIMOとしてそれを確認することを迷わずにいました。しかし、私は答えが間違っている方がよいアイデアではないと誰かを誤解させる可能性があるので、私はそれを削除しました。 –

+0

答え、ジリありがとう。 –

8

zahlから1の減算を繰り返しは、最終的には、この範囲の整数の整数であなたの1.(浮動小数点減算を与える正確なです:あなた2の53乗を超える奇妙なことしか得られない)。

あなたの問題は、JVMがおそらく多くの再帰呼び出しを許可していないことです。

スタックの深さが100万に近づいても、実際にはうまくいっていません。

+0

2 ^^ 54までの整数がエラー無く表現されていることに言及してください。 +1 64ビット浮動小数点は53ビットの仮数を持ちます。なぜなら、上位ビットは常に正規化された数に対して1であり、下位52ビットのみが格納される必要があるからです。 2 ^^ 54は最後のok整数ですが、2の累乗ですが、2 ^^ 54 + 1は表現できません。 –

+0

Hum。私たちは真ん中で会うでしょう。私は表現することができない最初の数は2 ^^ 53 + 1だと思います。 – Bathsheba

1

スタックには無制限ではなく、Javaにテールコールの最適化機能はありません。最も簡単な解決策は、メソッド

return zahl * (zahl + 1)/2; 

理想的には、あなたがより現実的な方法を必要とする任意の健全な最適化を行うために

public static long sumUpTo(int n) { 
    return n * (n + 1L)/2; 
} 

を記述し、二重の代わりに使用することはありませんを持つことです。

+1

Upvoted。 1)テールコールスニペットの場合、2)クローズドフォームソリューションを書き込む時間が必要な場合。 – Bathsheba

+0

しかし、再帰はありません。 –

+0

@HansMüller確かに。再帰のレベルが入力の次数Nの場合、Javaのespでは再帰はめったに良い考えではありません。順序ログNは平衡二分木のように大丈夫です。 –

0

あなたのこの例は、this comment!にも非常によく示されていますが、この問題のその他の非常に詳細な説明と、それが起こる理由と対処方法についてもいくつか説明されています。

+1

これは可能な重複としてマークされる可能性があります。 –

+1

私はそれを考慮しましたが、一般的な質問と説明が違っていて、リンクに提供された回答のうちの1つだけが似ていたので、私はそれについてあまりよく分かりませんでした。だから、単に何かを台無しにしないで、私はその決定を自分自身よりも有能な人に任せます –