繁体   English   中英

使用java.math.BigDecimal避免浮点精度问题

[英]Avoid floating point precision issue using java.math.BigDecimal

我有一个由双精度值(从0到1)填充的矩阵。 为了方便起见,让我们讨论行和列。 我想对矩阵的double值进行归一化,以使每一列的所有行的总和返回1。此任务触发浮点精度问题,因为使用double ,总和永远不会返回1。所以我尝试了使用BigDecimal但结果略有不同。

这是我的代码:

    double[][] U = new double[6][1015];
    double[] sumPerCol = new double[db.size()+1];
    for(int i=0; i<U.length; i++){
        for(int j =0; j<U[i].length; j++){
            double x = new Random().nextDouble();
            U[i][j] = x;
            sumPerCol[j] += x;
        }
    }
    double[] sumPerCol2 = new double[db.size()+1];
    for(int i=0; i<U.length; i++){
        for(int j =0; j<U[i].length; j++){
            BigDecimal x = new BigDecimal(U[i][j],MathContext.DECIMAL128);
            BigDecimal tot = new BigDecimal(sumPerCol[j],MathContext.DECIMAL128);
            BigDecimal x2 = x.divide(tot,MathContext.DECIMAL128);
            U[i][j] = x2.floatValue();
            sumPerCol2[j] += U[i][j];
        }
    }
    for(double d : sumPerCol2){
        System.out.println(d);
    }

当然,我没有正确使用BigDecimal 有人可以帮忙吗?

没错,您不能安全地在双精度值上使用==。 但是您可能不需要。 归一化矩阵仅需要将每个元素除以相应列元素的总和。 如果要检查归一化,只需对元素求和并检查与1的差是否“很小”(您可以定义epsilon值,例如10 ^(-10)。

我在这里看不到使用BigDecimal的任何原因。 如果由于某种原因确实需要绝对精度,请使用有理数(分数)的适当实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM