简体   繁体   中英

Avoid floating point precision issue using java.math.BigDecimal

I have a matrix populated by double values (from 0 to 1). For convenience, let's talk about rows and columns. I want to normalize the double values of the matrix, so that the sum of all the rows, for each columns, returns 1. This task triggers a floating point precision issue since, using double , the sum will never return 1. So I tried using BigDecimal but the result slightly differs.

Here is my code:

    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);
    }

For sure, I'm not using BigDecimal properly. Can anyone help?

You are right that you cannot safely use == on double values. But you probably will not need that. Normalizing the matrix only requires to divide each element by the sum of the respective column elements. If you want to check for normalization, just sum up the elements and check whether the difference to 1 is "very small" (you can define an epsilon value, say 10^(-10).

I do not see any reason for using BigDecimal here. If for some reason, you really need absolute precision, use an appropriate implementation of rational numbers (fractions).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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