java 浮点精度 ( 0.1+0.2+...+1.00 ..or.. 1.00+0.99+0.98+...+0.1 )

java floating point accuracy ( 0.1+0.2+...+1.00 ..or.. 1.00+0.99+0.98+...+0.1 )

我正在备考,我解决了这个问题

加上 0.1+0.2+...+1.00 ..or.. 1.00+0.99+0.98+...+0.1

在 Java 中以什么顺序添加数字以获得更高的准确度?

由于这是一个等差级数,其和可以计算如下

Sn = n * (a1 + an) / 2

Sn ... sum
n  ... number of elements
a1 ... first element
an ... last element

由于您消除了大部分数字,这似乎是最佳解决方案。

任何 COBOL 程序员都能立即回答这个问题。

问题的重点是,如果你先把大数相加,当你把小数相加时,你就会失去精度。先加小号。

有一个结果表明,如果将一系列正数按递增顺序相加,可以获得更好的最坏情况误差界限。这个结果并不意味着,对于给定的正数序列,将数字按升序相加会得到更小的误差。

例证:

int main() {
  float f = 0, g = 1;
  for (int i = 1; i <= 99; i++) {
    char buf[42];
    float ff;
    sprintf(buf, "0.%02i", i);
    sscanf(buf, "%f", &ff);
    f += ff;
    sprintf(buf, "0.%02i", 100-i);
    sscanf(buf, "%f", &ff);
    g += ff;
  }
  f += 1;
  printf("%a %a\n", f, g);
}

打印

0x1.940002p+5 0x1.93fffep+5

所讨论的 100 个 float 的精确总和,可以通过将 fg 声明为 double 来计算(但留下 ff 作为 float), 是 0x1.93ffffff8p+5, 表示对 递减 顺序中的数字求和在这里获胜。

比对所有数字线性求和更好,你应该研究分治法(分别求和一半数组)。

这很像Precise sum of floating point numbers