当添加相同的数字时,为什么输出是不同的?
public class Test {
public static void main(String a[]) {
double[] x = new double[]{3.9, 4.3, 3.6, 1.3, 2.6};
System.out.println(">>>>>>> " + sum(x));
}
public static double sum(double[] d) {
double sum = 0;
for (int i = 0; i < d.length; i++) {
sum += d[i];
}
return sum;
}
}输出是:15.7
如果我交换值
double[] x = new double[] {2.6, 3.9, 4.3, 3.6, 1.3};我得到的输出为:15.700000000000001
如何获得相同的输出?
发布于 2014-01-27 05:55:22
发布于 2014-01-27 11:39:19
在浮点运算序列中的每一步,系统必须生成一个以浮点格式表示的结果。这可能会导致舍入错误,丢失一些信息。
当添加两个不同大小的数字时,较大的一个倾向于控制哪些位必须丢弃。如果将一个大的和小的数字相加,由于结果的大幅度,这个小数字的许多位将被舍入误差丢失。当添加类似大小的数字时,这种影响就会减少。先加几个小数字,把大震级数留到尾,使小数字的效果累积起来。
例如,以{ 1e17, 21.0, 21.0, 21.0, 21.0, 21.0, 21.0, 21.0, -1e17 }为例。如果不加四舍五入,准确的答案将是147。加上上面所示的顺序,得到112。每增加一个"21.0“必须四舍五入,以适应一个数量级在1e17左右。按绝对震级的升序加起来,得到144,更接近确切的答案。添加这7个小数字的部分结果正好是147,然后必须将其四舍五入,才能容纳一个大约1e17的数字。
发布于 2014-01-27 11:55:17
简单地将所有的值加在一起,无论如何都会导致一个相对较大的错误(或者更准确地说:当和已经是“大”时,这个错误将是“大”的,并且应该进一步添加“小”数字)。
作为减少数值误差的一种可能性,您可以考虑使用算法:
public static double kahanSum(double d[])
{
double sum = 0.0;
double c = 0.0;
for (int i=0; i<d.length; i++)
{
double y = d[i] - c;
double t = sum + y;
c = (t - sum) - y;
sum = t;
}
return sum;
}https://stackoverflow.com/questions/21373865
复制相似问题