Cpp 在计算中如何处理大数?

How does Cpp work with large numbers in calculations?

我有一个代码尝试使用梯形法则(请参阅 Trapezoid method 中的公式)以数值方式求解给定区间内函数的积分,现在,对于函数 sin(x )在区间[-pi/2.0,pi/2.0]内,等待积分为零。

在这种情况下,我将分区数 'n' 设为 4。问题是当我的 pi 有 20 位小数时它是零,有 14 位小数时它是 8.72e^( -17),则小数点后11位为零,小数点后8位为8.72e^(-17),小数点后3位为零。我的意思是,对于 pi 的不同近似值,积分为零或接近零的数字,但它没有明确的趋势

非常感谢您帮助我理解为什么会发生这种情况。 (我在 Dev-C++ 中做到了 运行)。

#include <iostream>
#include <math.h>
using namespace std;
#define pi 3.14159265358979323846
//Pi: 3.14159265358979323846
double func(double x){
    return sin(x);
    }

int main() {
    double x0 = -pi/2.0, xf = pi/2.0;
    int n = 4;
    double delta_x = (xf-x0)/(n*1.0);
    double sum = (func(x0)+func(xf))/2.0;
    
    double integral;
    
    for (int k = 1; k<n; k++){      
       // cout<<"func: "<<func(x0+(k*delta_x))<<" "<<"last sum: "<<sum<<endl;
        sum = sum + func(x0+(k*delta_x));     
       // cout<<"func + last sum= "<<sum<<endl;
    }
    integral = delta_x*sum;
    cout<<"The value for the integral is: "<<integral<<endl; 
    return 0;
}

OP 正在将 y=sin(x)-a 整合到 +a。各种测试使用不同的 a 值,都接近 pi/2.

该方法使用 -1.0 附近的值的线​​性求和,下降到 0,然后上升到接近 1.0。

此求和对最后一项的计算误差很敏感,因为最终的数学求和预计为 0.0。由于 start/end a 不同,错误也不同。

一个更稳定的结果是首先添加极端的 f = sin(f(k)) 值。例如sum += sin(f(k=1)),然后是 sum += sin(f(k=3)),然后是 sum += sin(f(k=2)) 而不是 k=1,2,3。特别是术语 x=f(k=3) 的形成可能与其 x=f(k=1) 较早的术语的负面影响有点不同,进一步使问题复杂化。

欢迎来到数值分析世界


如果代码使用全部 float 或全部 long double,则存在问题,只是程度不同。

问题不是因为使用了不精确的 pi 值(对于 FP 不可能有精确值,因为 pi 是无理数,而所有有限的 FP 都是有理数)。

很大程度上要归功于 x 的形成。可以尝试下面的方法来形成关于 0.0 对称的 x。比较 完全 x 以这种方式生成与 x 原始方式。

x = (x0-x1)/2 + ((k - n/2)*delta_x)


打印出准确的计算值以加深理解。

printf("x:%a y:%a\n", x0+(k*delta_x), func(x0+(k*delta_x)));