c++ - 如何提高浮点二阶导数计算的精度?

标签 c++ floating-point floating-accuracy

我编写了一个简单的程序来使用函数指针计算函数的一阶和二阶导数。我的程序计算出正确的答案(或多或少),但对于某些函数,准确性低于我想要的。

这是我要区分的函数:

float f1(float x) {
    return (x * x);
}

这些是导数函数,使用中心有限差分法:

// Function for calculating the first derivative.

float first_dx(float (*fx)(float), float x) {
    float h = 0.001;
    float dfdx;

    dfdx = (fx(x + h) - fx(x - h)) / (2 * h);
    return dfdx;
}

// Function for calculating the second derivative.

float second_dx(float (*fx)(float), float x) {
    float h = 0.001;
    float d2fdx2;

    d2fdx2 = (fx(x - h) - 2 * fx(x) + fx(x + h)) / (h * h);
    return d2fdx2;
}

主要功能:

int main() {
    pc.baud(9600);
    float x = 2.0;

    pc.printf("**** Function Pointers ****\r\n");
    pc.printf("Value of f(%f): %f\r\n", x, f1(x));
    pc.printf("First derivative: %f\r\n", first_dx(f1, x));
    pc.printf("Second derivative: %f\r\n\r\n", second_dx(f1, x));
}

这是程序的输出:

**** Function Pointers ****
Value of f(2.000000): 4.000000
First derivative: 3.999948
Second derivative: 1.430511

我对一阶导数的准确性感到满意,但我认为二阶导数相差太远(它应该等于~2.0)。

我对 float 的表示方式以及它们有时不准确的原因有了基本的了解,但是如何使二阶导数结果更加准确?我是否可以使用比中心有限差分法更好的方法,或者有什么方法可以使用当前方法获得更好的结果?

最佳答案

通过选择精度更高的类型可以提高精度。 float 当前定义为 IEEE-754 32 位数字,精度为 ~7.225 小数位。

您想要的是 64 位对应项:double,精度为 ~15.955 小数位。


这对于您的计算来说应该足够了,但值得一提的是 boosts implementation它提供四精度 float (128 位)。

最后The GNU Multiple Precision Arithmetic Library提供具有任意小数位数的类型以确保精度。

关于c++ - 如何提高浮点二阶导数计算的精度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57058837/

相关文章:

objective-c - 比较浮点值有多危险?

c++ - GSSAPI 获取用户名密码和构建凭证不适用于非登录用户

c++ - 从 Eigen::VectorXd 获取矩阵 View / block ,无需复制(共享内存)

c++ - 使用 float 时避免不稳定的小数字

bash - 如何根据语言环境变量格式化 float 以供显示?

floating-point - 为什么无法获得鼠标坐标作为浮点值?

c++ - 在 C++ 中处理极小的数字

c++ - 调试错误 -Abort() 已被调用

c++ - 嵌入式 C++ : to use exceptions or not?

在C中将 float 转换为二进制