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
的精确总和,可以通过将 f
和 g
声明为 double
来计算(但留下 ff
作为 float
), 是 0x1.93ffffff8p+5
, 表示对 递减 顺序中的数字求和在这里获胜。
比对所有数字线性求和更好,你应该研究分治法(分别求和一半数组)。
这很像Precise sum of floating point numbers
我正在备考,我解决了这个问题
加上 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
的精确总和,可以通过将 f
和 g
声明为 double
来计算(但留下 ff
作为 float
), 是 0x1.93ffffff8p+5
, 表示对 递减 顺序中的数字求和在这里获胜。
比对所有数字线性求和更好,你应该研究分治法(分别求和一半数组)。
这很像Precise sum of floating point numbers