Main Tutorials

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

About Author

author image
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.

Comments

Subscribe
Notify of
7 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
prashant
8 years ago

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
4 years ago

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

subes
8 years ago

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
9 years ago

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