2016-11-09 29 views
3

我對堆棧有點新,所以我不太確定我完全理解StackOverflowError的含義。我確實讀過它主要發生在遞歸中,永遠不會結束。修復Java中的StackOverflowError

public double calculateLeibniz(double pi, double x, long l) { 
    if (l == 10000) { 
     return pi; 
    } 
    if (l % 2 == 0) { 
     pi -= (1.0/x); 
     return calculateLeibniz(pi, x + 2.0, l + 1); 
    } else { 
     pi += (1.0/x); 
     return calculateLeibniz(pi, x + 2.0, l + 1); 
    } 
} 

我試圖用萊布尼茨方法計算PI,並認爲我會嘗試彎曲我的遞歸肌肉。我不確定它爲什麼會返回錯誤,因爲該方法設置爲在10000次迭代後終止。在那裏使用循環會更有效嗎?

+5

嗯,是的,你遞歸10,000次,這意味着你正在建立所有這些10,000個電話的堆棧。避免遞歸的一個原因正是因爲它做到了這一點,並且如果您的堆棧空間用完了,代碼將會失敗 - 這是顯而易見的事情。遞歸不一定是無限的,會導致問題 - 只要足夠大,就可以用盡堆棧空間。 –

+0

它並不一定意味着遞歸不會結束。你可能只是有太多的迭代來處理你的內存。嘗試在100之後終止以查看這是否修復了錯誤 – holtc

+0

遞歸通常是猴子解決方案。像你一樣的情況也可以使用迭代輕鬆解決。 – DwB

回答

2

10000是一個很深的堆棧! JVM無疑是在你達到你的「極限」之前爆炸出來的。我建議你迭代地而不是遞歸地重新實現你的方法。像這樣...

public double calculateLeibniz(double pi, double x, int l) { 
    while (l < 10000) { 
     if (l % 2 == 0) { 
      pi -= 1.0/x; 
     } else { 
      pi += 1.0/x; 
     } 
     x += 2.0; 
     ++l; 
    } 
    return pi; 
} 

在這種情況下,你的算法的堆棧深度很淺:1堆棧幀深,具體。