Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中arcin的逼近_C_Algorithm_Precision_Trigonometry_Taylor Series - Fatal编程技术网

C中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)

我有一个程序,可以计算基于泰勒级数的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 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);
}

您的代码和问题包括:

  • 显示Arcin的泰勒级数的图像文件有两个错误:x5项上有一个减号而不是加号,x的幂显示为xn,但应为x2n+1
  • Arcin的泰勒级数项中的x因子在每个项中增加x2,但您的公式
    a*((my_pow(2*i-1,2))/((2*i)*(2*i+1)*my pow(x,2))
    在每个项中除以x2。对于您询问的特定值-1,这并不重要,但对于除1之外的其他值,它将产生错误的结果
  • 当术语上的差异“大于或等于”你的ε时,你会问如何结束循环,但是,对于x的大多数值,你实际上想要小于(或者相反,你想要继续,而不是结束,当差异大于或等于时,正如你在代码中所示)
  • 泰勒级数是一种糟糕的函数求值方法,因为它的误差随着距离级数中心点的距离的增加而增加。像这样的函数的大多数数学库实现都使用minimax系列或与之相关的东西
  • 对从低阶项到高阶项的序列求值会导致先添加较大的值,然后再添加较小的值。由于浮点运算的性质,这意味着较小项的精度会丢失,因为较大值会“挤出”浮点格式的宽度。这种影响将限制任何结果的准确性
  • 最后,为了直接回答您的问题,按照您构建代码的方式,您可以直接更新
    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)));