C 高斯积分与双除法

C 高斯积分与双除法,c,integral,C,Integral,为了好玩,我试着用级数展开法计算从0到1的高斯积分。出于这个原因,我写了一个阶乘函数,它可以工作到20!(我勾选)然后我写下: int main(){ int n; long double result=0; for(n=0; n<=5; n++){ if(n%2==0){ result+=(((long double) 1/(long double)(factorial(n)*(2*n+1)))); } el

为了好玩,我试着用级数展开法计算从0到1的高斯积分。出于这个原因,我写了一个阶乘函数,它可以工作到20!(我勾选)然后我写下:

int main(){
    int n;
    long double result=0;
    for(n=0; n<=5; n++){
        if(n%2==0){
            result+=(((long double) 1/(long double)(factorial(n)*(2*n+1))));
        } else {
            result-=(((long double) 1/(long double)(factorial(n)*(2*n+1))));
        }
    }        
    printf("The Gaussian integral from 0 to 1 is %Lf\n", result);
}
intmain(){
int n;
长双结果=0;
对于
(长双精度)(阶乘(n)*(2*n+1)
中的(n=0;n),乘法为整数乘法,如果
阶乘的结果已接近所用整数类型的限制,则第一个乘法可能溢出

((长双精度)(阶乘(n))*(2*n+1)
,使第一次乘法是浮点乘法。

(长双精度)(阶乘(n)*(2*n+1)中
,乘法是整数乘法,如果
阶乘
的结果已接近所用整数类型的限制,则第一个乘法可能溢出


编写
((长双精度)(阶乘(n))*(2*n+1)
,使第一次乘法是浮点乘法。

几乎可以肯定您的整数类型溢出了。在C中,这是技术上未定义的行为

对于32位无符号整数,13!将溢出。对于64位,21!将溢出

如果您使用浮点
double
类型或类似
\uuu uint128
的扩展(我认为,如果您的编译器支持它,您的算法将存活更长的时间)


您遇到的另一个问题是,您正在逐步将减小大小的项添加到总数中。在处理浮点类型时,这从来都不是一个好主意。如果您以相反的顺序运行
for
循环,那么结果将更准确。

您几乎肯定是溢出了整数类型。在C中,这是te技术上未定义的行为

对于32位无符号整数,13!将溢出。对于64位,21!将溢出

如果您使用浮点
double
类型或类似
\uuu uint128
的扩展(我认为,如果您的编译器支持它,您的算法将存活更长的时间)


您遇到的另一个问题是,您正在逐步将减小大小的项添加到总数中。在处理浮点类型时,这从来都不是一个好主意。如果您以相反的顺序运行
for
循环,则结果将更准确。

您使用的是MinGW编译器(Windows的gcc端口),它与
long-double
类型存在问题。这是由于GCC的
long-double
实现与Microsoft的C库之间存在冲突。另请参阅


根据,定义
\uu USE\u MINGW\u ANSI\u STDIO
可以解决这个问题。否则,使用
double
就可以了。

您使用的是MINGW编译器(用于Windows的gcc端口),它与
long-double
类型存在问题。这是由于GCC的
long-double
实现与Microsoft的C库之间存在冲突。另请参阅



根据,定义
\u使用
可以解决这个问题。如果不是,使用
双精度
就可以了。

n@interjay是的。我必须假设问题中显示的代码不是溢出的代码。但是,假设一个阶乘函数对传递给它的值起作用,并返回一些整数er类型(未在问题中指定),整数乘以
2*n+1
是问题中明显的危险信号,立即转换为浮点是最简单的补救方法。OP声称“阶乘函数可以工作到20!”。我怀疑它甚至会溢出一个64位整数。所以我同意Pascal-这不是一个SSCCE。所以+1答案(即使我的答案更可爱)。@Bathsheba 20!~2.432902e+18接近64位带符号整数的极限。但是如果
factorial
返回一个64位带符号整数,为什么
factorial(5)
有什么麻烦吗?嗯……关于20!这个问题:这是一个幼稚的算法,设计的精度不高。但是,我检查了Wolfram,20!是正确的。
n@interjay是的。我必须假设问题中显示的代码不完全是溢出的代码。但是,假设一个阶乘函数适用于values传递给它并返回某个整数类型(问题中未指定),整数乘以
2*n+1
是问题中明显的危险信号,立即转换为浮点是最简单的补救方法。OP声称“阶乘函数可以工作到20!”。我怀疑它甚至会溢出一个64位整数。所以我同意Pascal-这不是一个SSCCE。所以+1答案(即使我的答案更可爱)。@Bathsheba 20!~2.432902e+18接近64位带符号整数的极限。但是如果
factorial
返回一个64位带符号整数,为什么
factorial(5)
有什么麻烦吗?嗯……关于20!这个问题:这是一个简单的算法,设计的精度不是很多位数。但是,我检查了Wolfram,20!是正确的。
阶乘(0)的结果是什么
?适合我:它是1,我在编写函数时解决了这个问题。您使用的编译器是什么?如果它是MinGW,它不能正确处理
长双精度
。供将来参考:最好在您的帖子中包含意外输出,如“奇怪的负数”中所示这两件事有助于解决问题。
factorial(0)的结果是什么
?适合我:它是1,我在编写函数时解决了这个问题。您使用的编译器是什么?如果它是MinGW,它不能正确处理
长双精度
。供将来参考:最好在您的帖子中包含意外输出,如“奇怪的负数”中所示以及您的预期输出。这两件事有助于解决问题。虽然精度为6位数,但它的工作效率为双精度。我如何能做得更多?答案中增加了改进建议