Search code examples
javagroovyfloating-accuracy

Groovy vs Java - difference in floating point accuracy


What could be the reason for difference in floating point accuracy here?

def "emi test"(){
        given:
        def P =  6000000.00
        def n = 20 * 12
        def r = (8.35/12)/100

        double emi_g = (P * r * (1+r).power(n))  / ((1+r).power(n) - 1)
        double emi_j= (P * r * Math.pow(1+r,n)) / (Math.pow(1+r,n)-1);
        expect:
        emi_g == emi_j
    }

result:

emi_g == emi_j
|     |  |
|     |  51501.177737160346
|     false
51501.177737160666

Solution

  • The issue is related to types.

    (1 + r).power(n) - 1 evaluates to a BigDecimal

    P * r * (1 + r).power(n) evaluates to a BigDecimal

    P * r * Math.pow(1 + r, n) evaluates to a Double

    Math.pow(1 + r, n) - 1 evaluates to a Double

    It isn't clear what your requirements are and whether or not you care about the precision being lost and knowing those requirements would help describe how to get the desired behavior. The answer to the question as asked...

    What could be the reason for difference in floating point accuracy here?

    Is because the expressions evaluate to different types and the rules associated with dividing a Double by a Double (and the fact that you are the numerator and denominator values are in a Double to begin with, as opposed to BigDecimial) cause you to lose some precision.