Here是个问题..
这是我到目前为止所做的,
#include <stdio.h>
#include <math.h>
long int factorial(int m)
{
if (m==0 || m==1) return (1);
else return (m*factorial(m-1));
}
double power(double x,int n)
{
double val=1;
int i;
for (i=1;i<=n;i++)
{
val*=x;
}
return val;
}
double sine(double x)
{
int n;
double val=0;
for (n=0;n<8;n++)
{
double p = power(-1,n);
double px = power(x,2*n+1);
long fac = factorial(2*n+1);
val += p * px / fac;
}
return val;
}
int main()
{
double x;
printf("Enter angles in degrees: ");
scanf("%lf",&x);
printf("\nValue of sine of %.2f is %.2lf\n",x,sine(x * M_PI / 180));
printf("\nValue of sine of %.2f from library function is %.2lf\n",x,sin(x * M_PI / 180));
return 0;
}
问题在于程序在0到180度之间完美地工作,但除此之外它会产生错误。当我将n
中的for (n=0;n<8;n++)
的值增加到8以上时,我会得到显着的错误..算法没有任何问题,我已经在我的计算器中进行了测试,程序似乎也没问题。我认为问题是由于数据类型的范围..我应该纠正什么摆脱这个错误?
感谢..
答案 0 :(得分:2)
15!
确实超出了32位整数可以容纳的范围。如果我是你,我会一直使用双打。
sin(x)
的泰勒系列对于较大的x值收敛得更慢。对于x外-π,π。我加上/减去2 *π的倍数以获得尽可能小的x。
答案 1 :(得分:2)
错误是由数据类型的范围引起的。在sine()中,你计算的是15的阶乘,这是一个很大的数字,并且不适合32位(这可能是你的系统上实现的long int)。要解决此问题,您可以:
答案 2 :(得分:0)
你可能遇到15问题!
我会打印出p,px,fac的值以及每次迭代的术语值,然后查看它们。
答案 3 :(得分:0)
你只在无限系列中包含8个术语。如果你在多项式方面考虑它一秒钟,你应该看到你没有足够的适合整个曲线。
事实是你只需要为0&lt; = x&lt; = \ pi;写函数;使用这些关系将遵循所有其他值:
sin(-x) = -sin(x)
和
sin(x+\pi;) = -sin(x)
和
sin(x+2n\pi) = sin(x)
我建议您使用这些来标准化您的输入角度,以使您的功能适用于所有角度。
你的代码中内置了很多低效率(例如,你不断重新计算很容易适合表查找的阶乘;你使用power()来在-1和+1之间振荡)。但首先要让它正常工作,然后加快速度。
答案 4 :(得分:0)
您需要缩小范围。注意,泰勒级数最接近零,而在负范围内,它是正的范围的(负)镜像。因此,简而言之:缩小范围(通过2 PI的模块)将其包裹在您具有最高精度的范围内。超过1/2 PI的范围越来越不准确,所以你也想使用公式:sin(1/2 PI + x)= sin(1/2 PI - x)。对于负值,使用公式:sin(-x)= -sin(x)。现在,您只需要在跨越整个范围时评估0 - 1/2 PI的间隔。当然,对于非常大的值,2 PI的模块化精度将受到影响。