Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.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 精密积分回路的结束条件_C_While Loop - Fatal编程技术网

C 精密积分回路的结束条件

C 精密积分回路的结束条件,c,while-loop,C,While Loop,我正在尝试使用梯形规则对函数1/((1+x^2)x^0.5)进行积分。我需要尽可能高的精度,因此我将增加条带数N,直到计算机无法识别连续N的总条带数之间的变化。但是,最终条件目前不起作用,导致连续积分。有人有比我现在的代码更好的建议吗 非常感谢,, 贝丝 #包括 #包括 #包括 双内(双x,双h,双y,双N,双总计) { 总计=总计+0.5*(1/(1+pow(x,2))*sqrt(x)); x=x+h; 而(x如果你想对你的数值积分进行自动细化,一种方法是观察积分的相对收敛性 double p

我正在尝试使用梯形规则对函数1/((1+x^2)x^0.5)进行积分。我需要尽可能高的精度,因此我将增加条带数N,直到计算机无法识别连续N的总条带数之间的变化。但是,最终条件目前不起作用,导致连续积分。有人有比我现在的代码更好的建议吗

非常感谢,, 贝丝

#包括
#包括
#包括
双内(双x,双h,双y,双N,双总计)
{
总计=总计+0.5*(1/(1+pow(x,2))*sqrt(x));
x=x+h;

而(x如果你想对你的数值积分进行自动细化,一种方法是观察积分的相对收敛性

double previous = 0;
double current = inter( x, (y-x)/(N-1), y, N, total ); // Solve some baseline
do
{
    N = N + 1000;
    h = (y-x)/(N-1);
    previous = current;
    current = inter( x, h, y, N, total );
} while( abs( current - previous ) / current > 0.001 );
当您在估算中观察到小于0.1%的相对细化后,该代码将停止。减小
0.001
将有效地提高您的精度。通常比较双精度的最佳方法是通过公差检查,如:

abs( a - b ) < k
abs(a-b)

其中,
k
是您希望达到的精度顺序的一些因素。

如果您希望对数值积分进行自动细化,一种方法是查看积分的相对收敛性

double previous = 0;
double current = inter( x, (y-x)/(N-1), y, N, total ); // Solve some baseline
do
{
    N = N + 1000;
    h = (y-x)/(N-1);
    previous = current;
    current = inter( x, h, y, N, total );
} while( abs( current - previous ) / current > 0.001 );
当您在估算中观察到小于0.1%的相对细化后,该代码将停止。减小
0.001
将有效地提高您的精度。通常比较双精度的最佳方法是通过公差检查,如:

abs( a - b ) < k
abs(a-b)

其中,
k
是您希望达到的精度顺序的一些因素。

由于f(x)->∞ 作为x->0。在本例中,我将范围更改为1到1000。我还使用了求和函数来最小化对大量值求和时的舍入误差。来自wolframalpha的积分~=.487474,此程序将得到~=.487475。使用此链接可以找到精确的积分:

#包括
#包括
#包括
/*清晰阵列*/
无效清除量(双asum[2048])
{
尺寸i;
对于(i=0;i<2048;i++)
asum[i]=0。;
}
/*在数组中添加一个数字*/
void addtosum(双d,双asum[2048])
{
尺寸i;
而(1){
/*i=d的指数*/
i=((size_t)((*(unsigned long*)和d)>>52))&0x7ff;
如果(i==0x7ff){/*最大指数,则可能溢出*/
asum[i]+=d;
返回;
}
if(asum[i]==0。){/*if空插槽存储d*/
asum[i]=d;
返回;
}
d+=asum[i];/*否则将插槽添加到d,清除插槽*/
asum[i]=0./*并继续,直到插槽为空*/
}
}
/*从数组返回和*/
双返回和(双asum[2048])
{
双和=0。;
尺寸i;
对于(i=0;i<2048;i++)
总和+=asum[i];
回报金额;
}
双外汇(双x)
{
返回1./((1.+x*x)*sqrt(x));
}
双内(双x、双y、双n)
{
双asum[2048];/*用于求和函数*/
双h;
双d;
如果(n<1.){
n=1。;
h=0。;
}否则{
h=(y-x)/(n-1.0);
}
y-=h/2。;
晴朗(asum);
d=0.5*h*fx(x);
addtosum(d,asum);
对于(;x
使用辛普森法则,结果更准确,收敛于n的更小值:

#include<stdio.h>
#include<math.h>
#include<float.h>

/* clear array */
void clearsum(double asum[2048])
{
size_t i;
    for(i = 0; i < 2048; i++)
        asum[i] = 0.;
}

/* add a number into array */
void addtosum(double d, double asum[2048])
{
size_t i;
    while(1){
        /* i = exponent of d */
        i = ((size_t)((*(unsigned long long *)&d)>>52))&0x7ff;
        if(i == 0x7ff){         /* max exponent, could be overflow */
            asum[i] += d;
            return;
        }
        if(asum[i] == 0.){      /* if empty slot store d */
            asum[i] = d;
            return;
        }
        d += asum[i];           /* else add slot to d, clear slot */
        asum[i] = 0.;           /* and continue until empty slot */
    }
}

/* return sum from array */
double returnsum(double asum[2048])
{
double sum = 0.;
size_t i;
    for(i = 0; i < 2048; i++)
        sum += asum[i];
    return sum;
}

double fx(double x)
{
    return 1./((1.+x*x)*sqrt(x));
}

double simpson(double x, double y, double n) 
{
double asum[2048];              /* for summation functions */
double h;
double a;
    if(n < 1.){
        n = 1.;
        h = 0.;
    } else {
        h = (y-x)/(n-1.0);
    }
    y += h/2.;
    clearsum(asum);
    for( ; x < y; x += h){
        a = h/6.*(fx(x) + 4.*fx(x + h/2.) + fx(x + h));
        addtosum(a, asum);
    }
    a = returnsum(asum);
    return a;
}

int main()
{   
double x,y,n,value,newvalue;
    x=1.0;
    y=1000.;
    value=0.;

    for(n = 1000.; 1; n += 1000.)
    {   
        newvalue=simpson(x,y,n);
        printf("new value %.16lf %.0lf\n", newvalue, n);
        if(fabs(newvalue-value) < (newvalue*1E-10))
            break;
        value = newvalue;
    }
    return 0;
}
#包括
#包括
#包括
/*清晰阵列*/
无效清除量(双asum[2048])
{
尺寸i;
对于(i=0;i<2048;i++)
asum[i]=0。;
}
/*在数组中添加一个数字*/
void addtosum(双d,双asum[2048])
{
尺寸i;
而(1){
/*i=d的指数*/
i=((size_t)((*(unsigned long*)和d)>>52))&0x7ff;
如果(i==0x7ff){/*最大指数,则可能溢出*/
asum[i]+=d;
返回;
}
if(asum[i]==0。){/*if空插槽存储d*/
asum[i]=d;
返回;
}
d+=asum[i];/*否则将插槽添加到d,清除插槽*/
asum[i]=0./*并继续,直到插槽为空*/
}
}
/*从数组返回和*/
双返回和(双asum[2048])
{
双和=0。;
尺寸i;
对于(i=0;i<2048;i++)
总和+=asum[i];
回报金额;
}
双外汇(双x)
{
返回1./((1.+x*x)*sqrt(x));
}
双辛普森(双x,双y,双n)
{
双asum[2048];/*用于求和函数*/
双h;
双a;
如果(n<1.){
n=1。;
h=0。;
}否则{
h=(y-x)/(n-1.0);
}
y+=h/2。;
晴朗(asum);
对于(;x
由于f(x)->∞ 如x->0。在本例中,我将范围更改为1到1000。在对大量值求和时,我还使用了求和函数来最小化舍入误差。wolframalpha的积分为~=.487474,此程序得到的结果为~=.487475。使用t可以找到精确的积分