2013-05-03 85 views
-2

I的值必須計算的arctan(x)值。我已通過評估以下系列來計算此值:計算反正切(X)的C++中

Arctan(x)= x - x^3/3 + x^5/5 - x^7/7 + x^9/9 - ...

但下面的代碼無法計算出實際的價值。例如,calculate_angle(1)返回38.34。爲什麼?

const double DEGREES_PER_RADIAN = 57.296; 

double calculate_angle(double x) 
{ 
    int power=5,count=3; 
    double term,result,prev_res; 

    prev_res = x; 
    result= x-pow(x,3)/3; 

    while(abs(result-prev_res)<1e-10) 
    { 
     term = pow(x,power)/power; 
     if(count%2==0) 
      term = term*(-1); 
     prev_res=result; 
     result=result+term; 
     ++count; 
     power+=2; 
     // if(count=99) 
     // break; 
    } 

    return result*DEGREES_PER_RADIAN; 
} 
+0

我不會感到驚訝,如果38.34正是泰勒系列給你。這個增長很快。 – chris 2013-05-03 05:38:33

+0

如果我想要得到arc_tan(1)= 45度的值,該怎麼辦? – 2013-05-03 05:40:41

+0

值得一提的是,如果'| x | >> 0',此外[Wolframalpha建議](http://www.wolframalpha.com/input/?i=taylor-expand+arctan%28x%29)該系列是不同的'| x | <1'和'| x | > 1'。 – 2013-05-03 05:41:02

回答

3

編輯:我找到了罪魁禍首。您忘記包含功能abs所在的stdlib.h。您必須忽略關於abs被隱式聲明的警告。我檢查了刪除包含得出結果38.19,並且包括它得出結果〜45。

編譯器不要求停止編譯時被使用(在這種情況下絕對)未聲明的功能。相反,它允許假設函數是如何聲明的(在這種情況下,錯誤的)。

此外,像其他海報已經陳述,您使用abs是不合適的,因爲它返回一個int,而不是一個double或浮動。在此期間的情況應該是>1e-100而不是<1e-1001e-100也太小了。

-

你忘了增加countpower計算前兩個加數後:

prev_res = x; 
result= x-pow(x,3)/3; 

count = 4; <<<<<< 
power = 5; <<<<<< 

while(abs(result-prev_res)<1e-100) 
{ 
    term = pow(x,power)/power; 
    if(count%2==1) 
     term = term*(-1); 

此外,我認爲你的count變量違反直覺的使用:它intialized與3一樣,如果它表示最後使用的功率;但隨後,循環迭代通過1,而不是2增加它,你的count%2 == 1決定的標誌,而不是power%4 == 3

+0

請仔細檢查我的代碼。我增加了數量。 – 2013-05-03 05:46:09

+0

@OcenaPothik好吧,你在循環中增加它。那是你唯一需要增加它的地方嗎? – 2013-05-03 05:48:18

+0

它表示否定項。例如,如果count = 3,那麼我想確定第三項是否爲負號? – 2013-05-03 05:52:42

3

級數收斂曬黑^ { - 1} X,但不是非常快。考慮系列時x=1

1 - 1/3 + 1/5 - 1/7 + 1/9 - ... 

的結果是什麼1/9項截斷時錯誤?它大約在1/9。要獲得10^{-100}準確性,您需要擁有10^{100}條款。宇宙在你明白之前就會結束。而且,災難性的舍入誤差和截斷誤差會使答案完全不可靠。您只有14位數字可以玩double s。

請參閱Abramowitz和Stegun [AMS 55]或新的NIST數字函數庫http://dlmf.nist.gov等參考着作,以瞭解這些在實踐中是如何完成的。通常,使用Padé逼近而不是泰勒級數。即使你堅持使用泰勒級數,你也經常使用切比雪夫近似來減少總誤差。

我還建議數值中的方法[通常]工作,由福爾曼阿克頓。或...系列中的數字食譜。

+0

我可以通過標準庫中的函數輕鬆找到arctan(x)的值。那裏有什麼程序來找到值? – 2013-05-03 05:49:42

+1

你爲什麼不去看執行? – 2013-05-03 05:54:45

+0

我不知道。你可以試着看看你的平臺的文檔。這些通常在硬件支持的情況下以低級別完成;您的計算機的FPU可能有幫助的例程。 – 2013-05-03 05:55:03

2

你的星座是前兩項後,周圍的錯誤的方式。它應該是:

if(count%2==0) 
    term = term*(-1); 

你的比較是在while條件中錯誤的方法。此外,你期待的是一個不切實際的高精度水平。我建議更多的東西是這樣的:

while(fabs(result-prev_res)>1e-8) 

最後,你會得到更準確的結果與DEGREES_PER_RADIAN更好的價值。爲什麼不是這樣的:

const double DEGREES_PER_RADIAN = 180/M_PI; 
+0

我遵循了你的建議。但是我得到了像arctan(1)= 38.1973一樣的價值。爲什麼? – 2013-05-03 06:02:29

+1

對不起,我忘了在上面顯示的while條件中提到需要'fabs'而不是'abs'。 'abs'函數會給你一個整數結果,這在這裏顯然是無用的。 – 2013-05-03 06:24:18