天天看點

《C語言及程式設計》實踐參考——sin泰勒展式中的錯誤

【項目1-sin泰勒展式中的錯誤】

下面是sin函數的泰勒展式:

《C語言及程式設計》實踐參考——sin泰勒展式中的錯誤

(注:x取弧度值,而非角度值)

編寫了double mysin(double x)用于求sin值,卻“死”在了123°上(122°度的結果已經出來了)。劇透一下,循環沒有問題(當然問題會表現在循環中)。試着用調試工具找出問題出現在哪裡,然後給出解決問題的方案。

提示:請進入到mysin中後,注意各變量的變化,看通項是否會收斂,進而使循環能夠結束。

[參考解答]

(若需要參考,下面的錦囊逐個找開。你要是将所有錦囊全看了再幹,……老賀會傷心的:每個錦囊裡都有心血,一個一個做出來不容易。)

(若你在實施中,還有意外阻礙了你,請在評論中說明,幫助老賀細化錦囊。)

錦囊1:跟蹤要進到mysin函數中,注意用step into。

錦囊2:跟蹤mysin函數的執行,離不了進循環,你要是一直用next line(用step into不遇到自定義函數時效果也一樣),點滑鼠很單調,還容易分散注意力。請在循環中某語句上設定斷點,用debug/continue按鈕“跨越式”跟蹤。

《C語言及程式設計》實踐參考——sin泰勒展式中的錯誤

錦囊3:因為問題出在123°,你要是從0°開始跟蹤mysin中的循環,我相信你看到這個錦囊時,大概angle不超過10(這已經說明你有足夠的耐心了)。我們需要直接進入到對當角度是123°時對mysin的調用。有兩種方法:

第一種:改一下main函數,例如(還可以有很多方式,隻要能直接調用mysin(123°)即可):

第二種:在觀察視窗(watches)中,還可以在跟蹤中改變變量的值,以便看到對應的執行結果。是以如下圖,可以在進入到mysin函數之前,在觀察視窗中加入angle(需要在系統自動出現的變量的下面,自己再輸入變量名),然後在後面直接将想要的值輸入。

《C語言及程式設計》實踐參考——sin泰勒展式中的錯誤

其實還可以step into到mysin中後(或者通過斷點直接進入到mysin中後),同樣的辦法修改x的值。

錦囊4:很可能你聽了老賀的指點,用錦囊3中的第一種方法,卻發現進到mysin後,x的值是0,不是123°對應的弧度值。

對不起,我故意挖個坑,你也就進來了。進來了,坐會兒再走。

求123°的sin值,不是調用mysin((123/180)*pi),而是mysin((123.0/180)*pi)!mysin((123/180)*pi)的确就是mysin(0),注意資料類型。

進了這個坑,就要知道,程式的修改,可能會引入新的錯誤。這是軟體工程中的一個規律。

錦囊5:現在進入關鍵時刻(建議還是設好斷點跟蹤),你會發現問題在于,item的絕對值本來是逐漸遞減趨于0的(這展現了泰勒公式的收斂性,實際上,當角度值沒有達到123°時,這種收斂是能保證的),但是,某個時候,item的絕對值卻又大了起來,退出循環的希望,逐漸渺茫,以緻于失去了希望……你可以觀察fact的值,這裡也發生了一些似乎不可思議的事情。

《C語言及程式設計》實踐參考——sin泰勒展式中的錯誤

錦囊到此,現象都有了,下面就需要你的診斷了。請試着解決這個問題。解決了,或者實在想不出來了,再看下面的“真相”。

真相(倒着看,一來你得活動活動身體了,二來,實在不想讓你很容易地放棄自己給出解決方案的探索曆程):

《C語言及程式設計》實踐參考——sin泰勒展式中的錯誤

繼續閱讀