2011-11-04 93 views
2

我在大學學習C,而我是編程新手。我的任務是創建一個函數,它應該爲我的輸入計算一個弧線。遞歸調用函數時出現分段錯誤

我試圖用xcode進行調試。一切正常,直到返回arcsin(新);叫做。那麼它的一個分段錯誤:11。我不知道爲什麼,但浮點的斷點arcsin(floatvalue){...在運行第二個循環時告訴我浮動值和浮點值是NAN。

float arcsin(float value){ 

float old = value; 
float new = value + (0.5 * ((value * value * value)/3)); 
float accurate = 0.00001; 

    if ((new - old) < accurate){ 
    return new; 
    } 

    else{ 
    return arcsin(new); 
    } 
} 


int function_arcsin(int sigdig, float value){ 

    value = arcsin(value); 
    printf("%.10e\n",value); 

return 0; 
} 
+0

新是一個保留關鍵字。叫它像float newval – spicavigo

+2

@spicavigo:這是C,而不是C++,所以沒關係。 – bitmask

+0

@spicavigo不是普通的C. –

回答

2

當調用堆棧變得太大 - 即遞歸級別太多時,會發生seg錯誤。

就你而言,這意味着條件(new - old) < accurate將始終評估爲假 - 也許並不總是,但足夠的時間膨脹調用堆棧。

測試你的代碼我發現new(可能不是一個好的變量名稱選擇)一直在增長,直到超過float的極限。你的算法可能是錯誤的。

+0

'new'這個名字也讓我想起了一秒鐘,因爲它是C++中的一個關鍵字,但是這真的算作C中一個不好的選擇嗎? (我現在不熟悉C風格的規則)。 – Steve314

+1

@ Steve314你永遠不知道什麼時候你想要將代碼移植或包含到C++中,現在不妨選擇好,而不是稍後重構,對嗎? –

+1

@ Steve314這種無意義的變量名稱作爲'new'或'old'應該在任何語言中都被認爲是不好的選擇 –

0

我很確定分段錯誤是由太深的遞歸引起的。雖然許多編譯器可以將很多遞歸代碼優化爲迭代代碼,但有些編譯器卻不行,而且這很常見。調試選項來禁用它。

轉換爲迭代形式將停止段錯誤 - 但是,除非我錯過我的猜測,否則請給出無限循環。我不希望工作遞歸解決方案成爲一個問題在這裏,除非你正在測試超出範圍的近似值收斂 - 在這種情況下,我的第一個猜測是輸入範圍-pi到+ pi應該可以用於任何可用的近似弧線。

我並不熟悉arcsin的迭代逼近,而我的google-fu還沒有找到答案,但我懷疑你在float new = ...行中的計算錯了。

我發現這個鏈接...

http://mathforum.org/library/drmath/view/54319.html

這不是有益的 - 你的代碼是不是暗示描述這兩種方法的。

0

我測試你的程序,看到永遠不會結束循環:

((new - old) < accurate) // never is true 

,如果你用數字> 0嘗試,在10次迭代達到楠。用數字< 0,繼續數千次,並導致太深的遞歸。

相關問題