大浮点和的精度。

时间:2018-03-10 22:22:13

标签: c floating-point

我已经读过,当添加大量浮点数时,最好的方法是从最低到最高加总。我写了一个完全相同的代码但是从最高到最低的总和更精确,我不明白为什么,我问它here。我接受了一个答案,说这是因为在堆栈上创建了本地数组,其中空间有限。答案中的这段代码没有使用任何数组,因此它更精确:

#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;

是的,当输入为1000000000时,它更精确,如果输入是,例如1000我仍然有同样的问题。为什么呢?

1 个答案:

答案 0 :(得分:3)

从最低到最高计算的总和更准确;它与约1 ULP的精确结果不同,而从最高到最低计算的总和相差约7 ULP。

将1000项的和与无穷和相比较是错误的。前1000个项的精确数学和与无限和之间的差异远大于计算前一个和时出现的误差。 1000个术语的三个总和(精确数学,从最低到最高,从最高到最低)在彼此的8 ULP内,而无限系列的总和是4.5万亿ULP更高。

(此外,对π 2 / 6的估计是不准确的。您的程序有1.644934066848226。在IEEE 754基本64位二进制浮点(我将用于此答案),然而,1.6449340668482264060656916626612655818462371826171875更接近π 2 / 6。)

前1000个术语的确切数学总和接近1.6439345666815598031390580238222155896521034464937。这是使用Maple以扩展的精度计算的。最接近的可表示的值是1.6439345666815599056320706949918530881404876708984375。我将其称为最佳总和,因为它是最接近可能的任何计算总和可能是精确的数学值,因为没有可表示的值更接近。

从最高到最低计算的总和是1.643934566681561459944305170211009681224822998046875。这与最佳总和1.5543122344752191565930843353271484375e-15不同,即7 ULP。 (ULP是可向上调整可表示值的最小量;它是可表示值的步长.ULP是数字大小的函数;对于较大数字,它是更大的。) 7 ULP表示该数字与最佳总和相距7步。

从最低到最高计算的总和是1.643934566681559683587465769960545003414154052734375。这与最佳总和-2.220446049250313080847263336181640625e-16不同,在另一个方向上是1 ULP(低于最佳总和)。

因此,从最低到最高计算的总和更准确。

无限总和高出4.5万亿ULP。

因此,相对于最佳总和,数字按此顺序排列:

  • 从最低到最高计算的总和为-1 ULP。
  • 最佳总和是参考点,0 ULP。
  • 从最高到最低计算的总和为+7 ULP。
  • π 2 / 6是4.5万亿ULP。

现在很清楚,从最低到最高计算的总和离π 2 / 6更远,因为它位于最佳和的另一侧。但它更接近最佳总和。

在任何情况下,没有绝对的规则来计算从最低期到最高期的总和产生最佳答案。这是一般指导原则,基于错误较小而数字较小的概念。

每次在浮点数中添加两个数字时,可能会出现一个小错误,因为必须将精确的数学结果四舍五入为可表示的值。误差总是最多结果的1/2 ULP(因为,如果可表示的值超过精确数学结果的1/2 ULP,则正确方向上的下一个可表示值接近½ULP)。

然而,错误可以在0和½ULP之间变化,并且它们也可以是正的或负的。假设您添加了一系列随机数。有可能的是,在从最高到最低的位置添加数字时,我们会遇到正面和负面错误的混合,这些错误恰好会在很大程度上抵消,从而产生接近精确数学结果的最终结果。同时,从最低到最高添加数字可能会遇到很多正面错误,从而累积成大错误。

从最低幅度到最高幅度添加相同符号的数量往往会产生更好的结果,但这不是绝对的规则。

此外,如果数字是混合符号,选择要添加的数字以保持运行总和接近零可能是有利的,而不是总是选择下一个最低数量的数字。