高斯积分和双除法

时间:2014-08-28 14:37:18

标签: 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))));
        } else {
            result-=(((long double) 1/(long double)(factorial(n)*(2*n+1))));
        }
    }        
    printf("The Gaussian integral from 0 to 1 is %Lf\n", result);
}

这给了我一个奇怪的负数,显然不是很接近。我怀疑问题出在演员身上,但我不知道它是什么。有什么想法吗?这不是我尝试的第一件事。我尝试在表达式中转换任何内容并在开头放置显式转换,但它没有用。

3 个答案:

答案 0 :(得分:3)

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

根据this question,定义__USE_MINGW_ANSI_STDIO可以解决此问题。如果没有,则使用double代替。

答案 1 :(得分:2)

(long double)(factorial(n)*(2*n+1)中,乘法是整数乘法,如果factorial的结果已经接近所用整数类型的限制,则第一个乘法可能会溢出。

((long double)(factorial(n))*(2*n+1),以便第一次乘法是浮点乘法。

答案 2 :(得分:2)

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

对于32位无符号整数,13!会溢出来的。在64位,21!会溢出。

如果您使用浮点double类型或类似__uint128的扩展名(我认为,最多34个!),如果您的编译器支持它,您的算法将会存活一段时间。

您遇到的另一个问题是,您正在逐步添加缩小尺寸的条款。使用浮点类型时,这绝不是一个好主意。如果以相反的顺序运行for循环,则结果将更准确。