Wednesday, November 27, 2019

Monetary calculations in Java Using float or double !!!

Monetary calculations in Java :

Money plays an important factor in life and a Software engineer has to deal with money calculations like monetary arithmetic a lot during software development. If it is an e-commerce or banking application, then most of the calculations are on money only. But sometimes 0.01 value also makes the whole monetary arithmetic wrong.  That time we trigger our mind button and keeps on debugging, calculations manually bla bla bla !!! But in the end we sometimes weren't able to find the solutions; but actually, the solutions are dancing in-front, but we are not able to catch it.

When you deal with “money” value, always a question arises – Should I use double or float datatype to represent the monetary values?
Answer: Neither double nor float. Oh, boss!!!!! Why and what should I use ??

Why not double/float :

Let's take an example :

double amount1 =2.15;
double amount2 =1.10;
while( (amount1-amount2) !=1.05){
   System.out.println("Oh!!! Stil not true... I am getting stuck infinite lopp...but why...");
}

Output:
Infinite loop. . . .......................
............................

This code will result in an infinite loop because the result of subtraction of amount1 and amount 2 will not be 1.5 instead it would be "1.xxxxxxxxxxxxx" which make boolean condition always true.

System.out.println(2.00-1.1); // check the o/p

System.out.println(42/85); //check the o/p


Solution :

This is one of the common mistakes Java programmers make until they are familiar with BigDecimal class. We can avoid the above mistakes by using BigDecimal class as follows :


BigDecimal amount1 =new BigDecimal("2.15");
BigDecimal amount2 =new BigDecimal("1.10");
while( ! new BigDecimal((amount1.subtract(amount2).equals(new BigDecimal("1.05"))))
   System.out.println("Oh!!!  I am safe now. . .);
}

Output:
The difference of two amount is 1.05 and as the condition evaluates to false, no o/p will come.

Using Incorrect BigDecimal constructor

Another mistake Java Programmers make is using the wrong constructor of BigDecmialBigDecimal has an overloaded constructor and if you use the one which accepts double as an argument you will get the same result as you do while operating with double. So always use BigDecimal with String constructor. here is an example of using BigDecmial constructed with double values:

//Creating BigDecimal from double values
BigDecimal amount3 = new BigDecimal(2.15);
BigDecimal amount4 = new BigDecimal(1.10) ;
System.out.println("difference between 2.15 and 1.0 using BigDecmial is: " + (amount3.subtract(amount4)));

Output:
difference between 2.15 and 1.0 using double is: 1.0499999999999998
difference between 2.15 and 1.0 using BigDecmial is: 1.049999999999999822364316059974953532218933105468750

Conclusion :

  • Don’t use float and double on monetary calculation.
  • Use BigDecimal, long or int for monetary calculation.
  • Use BigDecimal with String constructor and avoid double one.
  • Use Money API (JSR-354

Note :

The performance of BigDecimal operations is slower than the performance of primitive types such as double, float . 

No comments:

Post a Comment