Search code examples
javadoublebigdecimal

Double to BigDecimal, comparing both


I have to do a double comparison, I have tried many things, but nothing really works.. they are responsible for stopping a cycle. First off, compared double's them selves using (double) Math.round(x*10000000)/10000000, worked fine but then.. Numbers were the same, but weren't(and vice versa), so the cycle continued endlessly. Tried rounding them and comparing long values, still the same. Lastly, tried using Big-decimal, ran into problems yet again.

BigDecimal value=new BigDecimal(Double.toString(decimalNumber),MathContext.DECIMAL32);  

BigDecimal temp=new BigDecimal(Double.toString((1/count)*sum),MathContext.DECIMAL32);  

Whats wrong with this code? As far as i know, it's best to use the string constructor, so I'm using it. The second line returns a juicy "java.lang.NumberFormatException", if I edit the 2nd line to, for example, 5.3222, after a while, the first line returns the same error. Should I replace doubles with BigDecimals, only for this comparison? That seems silly to me, there has to be an easy way to do this comparison.

I'm trying to compare doubles, with precision at least 1*10^-7.

Thanks in advance!


Solution

  • Given the large range that floating numbers have, to compare how close two floating point numbers are to each other you would usually use a relative difference.

    The relative difference between x and y is Math.abs((x-y)/x). You may consider x and y equal if the relative difference is below a certain threshold, for example:

    if (Math.abs((x-y)/x) < 1e-9) {
        // x is nearly equal to y
    }
    

    Update: This implementation has a few problems though:

    • It is not symmetric: if x = y we also expect y = x.
    • If x or y is zero, they compare always as unequal because the relative difference is either 1 or infinity.
    • If x and y both are zero, they compare as unequal because the left side calculates 0/0 (NaN)

    A better implementation first checks if x and y are close to zero, and divides by the largest or smallest. You can read more about this problem in Bruce Dawson's Comparing floating point numbers.