c++做業題sin公式

今日 有一位一樣讀大一的朋友向我求助有關c++的做業題 他說他的程序邏輯正確 可是結果的精度不對c++

題目以下:


函數

這是一道看起來十分簡單的做業題 我按照要求快速地寫了一個版本 不出所料 同樣遇到了精度問題spa

爲何會出現這種問題?3d

首先 計算機中的浮點數是不夠精確的 這是爲了運算速度所作的犧牲code

在我寫的代碼中 使用的是double 爲了使結果精確 要能儘可能減小沒必要要的計算過程blog

而我用了cmath頭文件中的pow函數 這使得double會被計算不少次致使結果精度下降ci

因而我決定寫一個無pow版本 從公式出發 思路以下:class

原式化簡:變量

sin(x) = x/1! - x^3/(1!*2*3) + x^5/(3!*4*5) - x^7/(5!*6*7) ...

拆分:循環

sin(x)= x/1!
	- x^3/(1!*2*3)
	+ x^5/(3!*4*5)
	- x^7/(5!*6*7)
	...

拆分以後咱們能夠嘗試用一個變量去替換其中的數字:

sin(x)= x/1!
[i=1] - x^3/(i!*(i+1)*(i+2))
[i=3] + x^5/(i!*(i+1)*(i+2))
[i=5] - x^7/(i!*(i+1)*(i+2))
[i=n] ...

引入一個變量p 替換冪:

p=x
sin(x)= p/1!
[i=1,p=p*x*x] - p/(i!*(i+1)*(i+2))
[i=3,p=p*x*x] + p/(i!*(i+1)*(i+2))
[i=5,p=p*x*x] - p/(i!*(i+1)*(i+2))
[i=n,p=p*x*x] ...

再引入一個變量f 替換階乘:

f=1
p=x
sin(x)= p/f
[i=1,p=p*x*x,f=f*(i+1)*(i+2)] - p/f
[i=3,p=p*x*x,f=f*(i+1)*(i+2)] + p/f
[i=5,p=p*x*x,f=f*(i+1)*(i+2)] - p/f
[i=n,p=p*x*x,f=f*(i+1)*(i+2)] ...

再引入一個變量n 替換其中的負號:

n=1
f=1
p=x
sin(x)= p/f
[i=1,p=p*x*x,f=f*(i+1)*(i+2),n=-n] + n*p/f
[i=3,p=p*x*x,f=f*(i+1)*(i+2),n=-n] + n*p/f
[i=5,p=p*x*x,f=f*(i+1)*(i+2),n=-n] + n*p/f
[i=n,p=p*x*x,f=f*(i+1)*(i+2),n=-n] ...

如今每項的式子徹底相同了 只需將其轉換成對應的程序
咱們要考慮結束條件 即當其中一項的絕對值小於1.0e-7時 結束這個循環

最終答案 :

 1 double x;
 2 cout << "請輸入角度值:";
 3 cin >> x;
 4 
 5 x = x * 3.141592654 / 180;
 6 
 7 double n = 1;
 8 double f = 1;
 9 double p = x;
10 double i = -1;
11 
12 double term = 0;
13 double result = p / f;
14 
15 while (1)
16 {
17     i += 2;
18     p = p * x * x;
19     f = f * (i + 1) * (i + 2);
20     n = -n;
21     term = p / f;
22     if (term < 1.0e-7)
23         break;
24     result = result + n * term;
25 }
26 cout << "對應的sin值爲:" << result << endl;

結果正確:

 

再看看朋友的代碼:

 1 double angel,term,sum=0,i=1,multi=1,sign=-1;
 2 const double pi=3.141592654;
 3 cout<<"請輸入角度值:";
 4 cin>>angel;
 5 angel=angel*pi/180;
 6 term=angel;
 7 while(term>=1.0e-7||term<=-1.0e-7)
 8 {
 9     sum+=term;
10     angel*=angel*angel;
11     multi*=(i+1)*(i+2);
12     term=sign*angel/multi;
13     sign*=-1;
14     i+=2;
15 }
16 cout<<"對應的sin值爲:"<<sum<<endl;

結果:

思路大體和我相同 可是其中一步 angel*=angel*angel; 不對
在個人代碼中 這一步對應的是 p = p * x * x; 其中x是不變的 他代碼的這一部分並不等效於sin公式

END

相關文章
相關標籤/搜索