简体   繁体   中英

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

The difference is explained by the data type of the results.

When run in a shell, the types of your results are:

groovy:000> emi_g.getClass()
===> class java.math.BigDecimal
groovy:000> emi_j.getClass()
===> class java.lang.Double

Groovy's implementation returns a BigDecimal , which has better precision than Double

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.

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