fab*_*sgc 5 c algorithm pi trigonometry
对于我的学习,我必须编写一个算法来计算sin()这个函数:


但是,在我的算法中,我必须将X的值保持在0和Pi/2之间.所以,我编写了算法,但所有结果都是错误的.
这是我的代码:
double sinX(double x){
double resultat = 0;
int i;
if(x < 0 || x > M_PI_2)
x = fmod(x,M_PI_2);
for(i = 1;i<=30;i++){
resultat += -1 * ((x*x)/(2*i*(2*i+1)))*(pow(-1,i-1))*((pow(x,2*i-1))/(factorielle(2*i-1)));
}
return resultat;
}
Run Code Online (Sandbox Code Playgroud)
我没有找到原因.你能帮助我吗?
这里是X的几个值和fmod的结果
1 / 1
2 / 0.429204
3 / 1.4292
4 / 0.858407
5 / 0.287611
6 / 1.28761
7 / 0.716815
8 / 0.146018
9 / 1.14602
10 / 0.575222
11 / 0.00442571
12 / 1.00443
13 / 0.433629
14 / 1.43363
15 / 0.862833
16 / 0.292037
17 / 1.29204
18 / 0.72124
19 / 0.150444
20 / 1.15044
Run Code Online (Sandbox Code Playgroud)
以及算法的结果
1 / -0.158529
2 / -0.0130568
3 / -0.439211
4 / -0.101605
5 / -0.00394883
6 / -0.327441
7 / -0.0598281
8 / -0.000518332
9 / -0.234888
10 / -0.0312009
11 / -1.44477e-008
12 / -0.160572
13 / -0.0134623
14 / -0.443022
15 / -0.103145
16 / -0.00413342
17 / -0.330639
18 / -0.0609237
19 / -0.000566869
20 / -0.237499
Run Code Online (Sandbox Code Playgroud)
这是我的"factorielle"定义
double factorielle(double x){
double resultat = 1;
int i;
if(x != 0){
for (i=2;i<=x;i++)
{
resultat *= i;
}
}
else{
resultat = 1;
}
return resultat;
}
Run Code Online (Sandbox Code Playgroud)
和价值观:
1 / 1
2 / 2
3 / 6
4 / 24
5 / 120
6 / 720
7 / 5040
8 / 40320
9 / 362880
10 / 3.6288e+006
11 / 3.99168e+007
12 / 4.79002e+008
13 / 6.22702e+009
14 / 8.71783e+010
15 / 1.30767e+012
16 / 2.09228e+013
17 / 3.55687e+014
18 / 6.40237e+015
19 / 1.21645e+017
20 / 2.4329e+018
Run Code Online (Sandbox Code Playgroud)
你误解了你展示的第二个公式的目的.我们的想法是,您使用该公式计算前一项中总和的每个项,从而使您无需使用任何pow或factorial调用.
#include <stdio.h>
double sinX(double x) {
double term, total_so_far;
int i;
term = x; /* First term in the expansion. */
total_so_far = 0.0;
for (i = 1; i <= 30; i++) {
/* Add current term to sum. */
total_so_far += term;
/* Compute next term from the current one. */
term *= -(x * x) / (2*i) / (2*i + 1);
}
return total_so_far;
}
int main(void) {
/* testing */
double x;
int i;
for (i = 0; i <= 10; i++) {
x = i / 10.0;
printf("sin(%f) is %f\n", x, sinX(x));
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以及在我的机器上运行此代码的结果:
sin(0.000000) is 0.000000
sin(0.100000) is 0.099833
sin(0.200000) is 0.198669
sin(0.300000) is 0.295520
sin(0.400000) is 0.389418
sin(0.500000) is 0.479426
sin(0.600000) is 0.564642
sin(0.700000) is 0.644218
sin(0.800000) is 0.717356
sin(0.900000) is 0.783327
sin(1.000000) is 0.841471
Run Code Online (Sandbox Code Playgroud)
这应该给你的范围内合理的结果0来pi / 2.在该范围之外,你需要对你正在使用的减少更加谨慎:简单地减少模数pi / 2将不会给出正确的结果.(提示:它是安全的,以减少模2 * pi,因为sin功能是周期性的,周期2 * pi现在使用的对称.sin功能降低到范围0到pi / 2.)
编辑解释为什么当前代码给出了错误的结果:除了有缺陷的减少步骤之外,在你的总和中你从术语开始i = 1.但第一个术语应该是i = 0(这个x术语,而i=1术语是-x^3 / 3!术语).快速而肮脏的修复方法是删除还原步骤,并将resultat变量初始化为x而不是0.那应该给你小的好结果x,然后你可以弄清楚如何更换减少步骤.如果您真的打算使用显式因子和功率调用来计算答案,我会感到惊讶,但我几乎可以肯定,如上所述,您可以预期从前一个项计算每个项.