How to calculate monetary values in Java

There are many monetary values calculation in the financial or e-commerce application, and there is one question that arises for this – Should we use double or float data type to represent the monetary values?

Answer: Always uses java.math.BigDecimal to represent the monetary values.

1. Double or Float?

Here is an example of using double and float to represent the monetary values in Java.

JavaMoney.java

package com.mkyong;

import java.text.DecimalFormat;

public class JavaMoney {

    private static DecimalFormat df = new DecimalFormat("0.00");

    public static void main(String[] args) {

        System.out.println(2.00 - 1.1);
        System.out.println(2.00 - 1.2);
        System.out.println(2.00 - 1.3);
        System.out.println(2.00 - 1.4);
        System.out.println(2.00 - 1.5);
        System.out.println(2.00 - 1.6);
        System.out.println(2.00 - 1.7);
        System.out.println(2.00 - 1.8);
        System.out.println(2.00 - 1.9);
        System.out.println(2.00 - 2);

        System.out.println("--------------------");

        double i = 2.0;
        double j = 1.7;

        System.out.println("double : " + (i - j));
        System.out.println("double : " + df.format(i - j));

        float i2 = 2.0f;
        float j2 = 1.7f;

        System.out.println("float : " + (i2 - j2));
        System.out.println("float : " + df.format(i2 - j2));

    }

}

Output – It cannot calculate all the decimals precisely.


0.8999999999999999
0.8
0.7
0.6000000000000001
0.5
0.3999999999999999
0.30000000000000004
0.19999999999999996
0.10000000000000009
0.0
--------------------
double : 0.30000000000000004
double : 0.30
float : 0.29999995
float : 0.30

2. BigDecimal

To avoid the decimal issue above, we can use BigDecimal to represent the monetary values; furthermore, we can control the BigDecimal scale much more straightforward.

JavaMoney2.java

package com.mkyong;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class JavaMoney2 {

    public static void main(String[] args) {

        System.out.println("--- BigDecimal-----");
        System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.1)));
        System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.2)));
        System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.3)));
        System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.4)));
        System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.5)));
        System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.6)));
        System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.7)));
        System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.8)));
        System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(1.9)));
        System.out.println(BigDecimal.valueOf(2.00).subtract(BigDecimal.valueOf(2)));

        System.out.println("--------------------");

        BigDecimal i = BigDecimal.valueOf(2.0);
        BigDecimal j = BigDecimal.valueOf(1.7);

        System.out.println("double : " + i.subtract(j));
        System.out.println("double : " + i.subtract(j).setScale(5, RoundingMode.HALF_UP));

    }

}

Output – BigDecimal performs exact decimal arithmetic.


--- BigDecimal-----
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0.0
--------------------
double : 0.3
double : 0.30000

References

author image

mkyong

Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities. Read all published posts by

Comments

avatar
3000
newest oldest most voted
prashant
Guest
prashant

how java decides the double precision
ex:
10.2*2 = 20.4
10.3*3=30.599999999999998
why the result is different in both cases?

Sergey Ponomarev
Guest
Sergey Ponomarev

There is a library JavaMoney that simplifies a lot of things https://javamoney.org/

subes
Guest
subes

See https://github.com/subes/invesdwin-util#decimal for an alternative to working with Double directly by using a fluent API around it that is very fast since being designed for financial strategy backtesting.

Prateek Ashtikar
Guest
Prateek Ashtikar

Very useful. I was struggling to do precisely calculations. Thanks!!