首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当按不同的顺序添加相同的双倍时,结果不同

当按不同的顺序添加相同的双倍时,结果不同
EN

Stack Overflow用户
提问于 2014-01-27 05:50:26
回答 4查看 2.8K关注 0票数 16

当添加相同的数字时,为什么输出是不同的?

代码语言:javascript
运行
复制
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

如果我交换值

代码语言:javascript
运行
复制
double[] x = new double[] {2.6, 3.9, 4.3, 3.6, 1.3};

我得到的输出为:15.700000000000001

如何获得相同的输出?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-01-27 05:55:22

浮点数失准随着您做更多的操作。通常,首先添加最小的数字才能获得最高的精度。(因此结果确实取决于操作的顺序)

除了保持相同的操作顺序之外,您还必须使用严格在不同的平台上获得相同的结果。

或者更好的是,不要使用浮点数:使用BigDecimal代替。

票数 12
EN

Stack Overflow用户

发布于 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的数字。

票数 3
EN

Stack Overflow用户

发布于 2014-01-27 11:55:17

简单地将所有的值加在一起,无论如何都会导致一个相对较大的错误(或者更准确地说:当和已经是“大”时,这个错误将是“大”的,并且应该进一步添加“小”数字)。

作为减少数值误差的一种可能性,您可以考虑使用算法

代码语言:javascript
运行
复制
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;        
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21373865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档