大浮点和的精度

问题描述 投票:6回答:2

我试图总结一个正向递减浮点的排序数组。我已经看到,总结它们的最佳方法是开始将数字从最低到最高加起来。我写这个代码的例子是,但是,从最高数字开始的总和更精确。为什么? (当然,总和1 / k ^ 2应为f = 1.644934066848226)。

#include <stdio.h>
#include <math.h>

int main() {

    double sum = 0;
    int n;
    int e = 0;
    double r = 0;
    double f = 1.644934066848226;
    double x, y, c, b;
    double sum2 = 0;

    printf("introduce n\n");
    scanf("%d", &n);

    double terms[n];

    y = 1;

    while (e < n) {
        x = 1 / ((y) * (y));
        terms[e] = x;
        sum = sum + x;
        y++;
        e++;
    }

    y = y - 1;
    e = e - 1;

    while (e != -1) {
        b = 1 / ((y) * (y));
        sum2 = sum2 + b;
        e--;
        y--;
    }
    printf("sum from biggest to smallest is %.16f\n", sum);
    printf("and its error %.16f\n", f - sum);
    printf("sum from smallest to biggest is %.16f\n", sum2);
    printf("and its error %.16f\n", f - sum2);
    return 0;
}
c floating-point precision numerical-methods
2个回答
5
投票

您的代码在堆栈上创建了一个数组double terms[n];,这对程序崩溃之前可以执行的迭代次数设置了一个硬性限制。

但是你甚至都没有从这个数组中获取任何东西,所以没有理由把它放在那里。我改变了你的代码以摆脱terms[]

#include <stdio.h>

int main() {

    double pi2over6 = 1.644934066848226;
    double sum = 0.0, sum2 = 0.0;
    double y;
    int i, n;

    printf("Enter number of iterations:\n");
    scanf("%d", &n);

    y = 1.0;

    for (i = 0; i < n; i++) {
        sum += 1.0 / (y * y);
        y += 1.0;
    }

    for (i = 0; i < n; i++) {
        y -= 1.0;
        sum2 += 1.0 / (y * y);
    }
    printf("sum from biggest to smallest is %.16f\n", sum);
    printf("and its error %.16f\n", pi2over6 - sum);
    printf("sum from smallest to biggest is %.16f\n", sum2);
    printf("and its error %.16f\n", pi2over6 - sum2);
    return 0;

}

如果以十亿次迭代运行,则最小的第一种方法要准确得多:

Enter number of iterations:
1000000000
sum from biggest to smallest is 1.6449340578345750
and its error 0.0000000090136509
sum from smallest to biggest is 1.6449340658482263
and its error 0.0000000009999996

1
投票

当您添加两个具有不同数量级的浮点数时,最小数字的低位数将丢失。

当你从最小到大的总和时,部分总和像Σ1/k²一样从k增长到N,即大约n(蓝色),与1/n-1/N相比。

当你从最大到最小的总和时,部分总和像1/n²那样从Σ1/k²增长到k,这是n(绿色)与N相比。

很明显,第二种情况会导致更多的位损失。

π²/6-1/n

© www.soinside.com 2019 - 2024. All rights reserved.