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

时间:2019-07-16 13:49:16

标签: 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)。

我对浮点数如何表示以及为什么有时不准确有基本的了解,但是我如何才能使二阶导数结果更准确?我可以使用比中央有限差分法更好的方法,还是可以用当前方法获得更好的结果?

2 个答案:

答案 0 :(得分:3)

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

您想要的是64位副本: double ,精度约为小数位数{15.955


这对于您的计算应该足够了,但是值得一提的是https://sandbox.2checkout.com/sandbox/notifications/ins_test,它提供了四精度浮点数(128位)。

最后,boosts implementation提供具有任意小数位数的精度类型。

答案 1 :(得分:2)

  • 进行分析。 ;-)可能不是“使用当前 方法”。
  • 使用double而不是float。
  • 改变epsilon( h ),并以某种方式组合结果。例如,您可以尝试0.00001、0.000001、0.0000001并将其取平均值。实际上,您希望结果具有最小的 h 且不会发生上溢/下溢。但是尚不清楚如何检测上溢和下溢。