C中arcin的逼近
我有一个程序,可以计算基于泰勒级数的Arcin值的近似值 我的朋友和我提出了一种算法,它能够返回几乎“正确”的值,但我认为我们做得不太清楚。看一看:C中arcin的逼近,c,algorithm,precision,trigonometry,taylor-series,C,Algorithm,Precision,Trigonometry,Taylor Series,我有一个程序,可以计算基于泰勒级数的Arcin值的近似值 我的朋友和我提出了一种算法,它能够返回几乎“正确”的值,但我认为我们做得不太清楚。看一看: double my_asin(double x) { double a = 0; int i = 0; double sum = 0; a = x; for(i = 1; i < 23500; i++) { sum += a; a = next(a, x, i)
double my_asin(double x)
{
double a = 0;
int i = 0;
double sum = 0;
a = x;
for(i = 1; i < 23500; i++)
{
sum += a;
a = next(a, x, i);
}
}
double next(double a, double x, int i)
{
return a*((my_pow(2*i-1, 2)) / ((2*i)*(2*i+1)*my_pow(x, 2)));
}
但是函数double next依赖于i,所以我想我也必须在while语句中增加它。你知道我该怎么做吗
-1的输出示例:
$ -1.5675516116e+00
而不是:
$ -1.5707963268e+00
非常感谢各位 所以我想我也必须在while语句中增加它 是的,这可能是一种方式。什么阻止了你
int i=0;
while(condition){
//do something
i++;
}
另一种方法是使用for条件:
for(i = 1; i < 23500 && my_abs(prev_term - next_term) >= EPSILON; i++)
for(i=1;i<23500&&my\u abs(上一个术语-下一个术语)>=EPSILON;i++)
您的公式错误。下面是正确的公式:
另请注意,您的公式和系列之间并不对应
您可以这样使用:
while( std::abs(sum_prev - sum) < 1e-15 )
{
sum_prev = sum;
sum += a;
a = next(a, x, i);
}
while(std::abs(sum_prev-sum)<1e-15)
{
sum_prev=sum;
总和+=a;
a=下一个(a,x,i);
}
您的代码和问题包括:
a*((my_pow(2*i-1,2))/((2*i)*(2*i+1)*my pow(x,2))
在每个项中除以x2。对于您询问的特定值-1,这并不重要,但对于除1之外的其他值,它将产生错误的结果a
,这样您就不会同时拥有上一学期和下一学期。相反,创建另一个double b
,以便为前一个术语创建对象b
,为当前术语创建对象a
,如下所示double a = x, b, sum = a;
int i = 0;
do
{
b = a;
a = next(a, x, ++i);
sum += a;
} while (abs(b-a) > threshold);
对于
arcin
使用Taylor级数是非常不精确的,因为这些东西收敛得非常糟糕,并且对于有限数量的therm,与真实的东西会有相对较大的差异。同样,使用整数指数的pow
也不是很精确和有效
但是,使用arctan
进行此操作是可以的
arcsin(x) = arctan(x/sqrt(1-(x*x)));
当它的泰勒级数在
范围内收敛正常时,可以通过它计算范围内的所有其他部分(使用三角恒等式)。下面是我的C++实现(来自我的算术模板):
T atan(常数T&x)/=atan(x)
{
bool _shift=false;
bool _invert=false;
bool _阴性=假;
T z,dz,x1,x2,a,b,int i,;
x1=x;如果(x11.0){u invert=true;x1=1.0/x1;}
如果(x1>0.7){u shift=true;b=::sqrt(3.0)/3.0;x1=(x1-b)/(1.0+(x1*b));}
x2=x1*x1;
对于(z=x1,a=x1,b=1,i=1;i0.8)而言,收敛速度较慢
{
a*=x2;b+=2;dz=a/b;z-=dz;
a*=x2;b+=2;dz=a/b;z+=dz;
如果(::abs(dz)我想我需要的是上一项和下一项的绝对值之间的差值,而不仅仅是将ε与一个数字进行比较。我要试一试。请注意,你的第一个公式是错误的,在Arcin的泰勒级数中,所有项都有一个+
符号。@MartinR我不认为这是错误的。@Foxxy,这显然是错误的。你怎么得到第三个呢所有术语都有一个+号。在你的next()
函数中似乎是正确的,只有公式的第一个屏幕截图是错误的。我删除了I的条件,因为它确实只是为了在某个点结束循环。for(I=1;my_abs(sum-a)>=EPSILON;I++)
只是给了我奇怪的值,所以我想它在第一个学期就失败了。我的abs(sum-a)是什么?我认为这个条件是错误的(TEM变得越来越小,所以这个差异越来越大)。再次检查您的想法。您可能还想使用问题评论中建议的条件@Nico Schertler。double prev_term=1;double next_term=0.5*(x/prev_term+prev_term);while(my_abs(prev_term-next_term)>=EPSILON){prev_term=next_term;next_term=0.5*(x/prev_term+prev_term)}return next_term;
这对我的平方根计算非常有效。@Foxxy,这能解决你的问题吗?至少有帮助吗?嘿,非常感谢你的输入。你的例子对我帮助很大,到目前为止产生了更好的结果。但是,我不太清楚你在第2点中的意思。我是否应该将公式改为递增e乘以x^2?目前,asin(1)的输出是1.2416667E+00
treshold 0.0000000000 1…@Foxxy:Point 2仅指出图像不正确。代码在这方面也不正确。值1.2416667E+0
arcsin(x) = arctan(x/sqrt(1-(x*x)));