Handling currency calculations in Java business application
March 29, 2009 8 Comments
Recently I saw a weird floating issue in Java application which made our currency calculation wrong. Can you guess what would be the output of the below code?
System.out.println(38.0 - 26.6);
With help of google search found this error is related to floating point arithmetic calculation. Sun recommends to use BigDecimal for currency calculation in Java. For example above code can be changed as below:
System.out.println(BigDecimal.valueOf(38.0).subtract(BigDecimal.valueOf(26.6)));
For database updates also BigDecimal object can be used as below:
PreparedStatement ps = connection .prepareStatement("UPDATE AccountBill SET AmountPaid=? WHERE BillNo=?"); ps.setBigDecimal(1, BigDecimal.valueOf(0.01)); ps.setInt(2, 12345); ps.executeUpdate();
Lesson Learned:
a) Don’t use float/double for exact values like money/currency.
b) Use BigDecimal for all currency values representation and its calculation.
I don’t have patience to go through below article, seems it explain the floating point arithmetic issue in detail.
That’s true venkat… I found out this in the last project where a specific subtraction gives value with infinite .99999999 at in the decimal portion where nothing is accepted…
In Java, if it is not mentioned explicitly, any arithmetic operation on numbers is of 2 types – int arithmetic of double. So, such problems arise in those cases. Even if you had typed, “38.0F – 26.6F”, the result would be what you expected and not something strange. Such explicit mention is required.
I haven’t tried with float initially. Today I tried it gives the expected result as you mentioned. It is strange that double and float behaves differently in arithmetic.
I don’t think so, Hari & Venkat. Both float and double values should never be used for exact answers because it is impossible to represent 0.1 (or any other negative power of ten) as a float or double exactly..
The example we took in the post is very simple, so float type has produced a correct result but that’s not the case for all calculations.
Take a look at the example code Josh Bloch’s Effective Java book. It is very simple..
public static void main(String[] args) {
double funds = 1.00;
int itemsBought = 0;
for (double price = .10; funds >= price; price += .10) {
funds -= price;
itemsBought++;
}
System.out.println(itemsBought + ” items bought.”);
System.out.println(“Change: $” + funds);
}
It should execute four times and print out this
4 items bought.
Change: $0.00
but with float and double it won’t do that. It prints out following in my machine..
Float Datatype
3 items bought.
Change: $0.39999998
Double datatype
3 items bought.
Change: $0.3999999999999999
Only when I restructure the primitive to BigDecimal in code, it prints out
4 items bought.
Change: $0.00
~Muthu
Note: the code sample posted here is taken from “Item 48: Avoid float and double if exact answers are required in Effective Java 2’nd Edition by Joshua Bloch”
Guyz,
It is not issue with Java alone, so many languages has the same problem.
http://sg2.php.net/float
Mohan
Pingback: Float, Double, BigDecimal : Handling currency calculations in Java business application « Wateron's Blog
Hi admin do you need unlimited articles for your page ? What if you could copy article from other blogs, make it unique and publish on your website – i know
the right tool for you, just search in google:
Ziakdra’s article tool
I am regular reader, how are you everybody? This post posted at this site is
in fact good.