Handling currency calculations in Java business application

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.

http://docs.sun.com/source/806-3568/ncg_goldberg.html

8 Responses to Handling currency calculations in Java business application

  1. 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…

  2. hariistou says:

    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.

  3. Venkat says:

    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.

  4. 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”

  5. Mohan says:

    Guyz,

    It is not issue with Java alone, so many languages has the same problem.
    http://sg2.php.net/float
    Mohan

  6. Pingback: Float, Double, BigDecimal : Handling currency calculations in Java business application « Wateron's Blog

  7. Tommy says:

    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

  8. I am regular reader, how are you everybody? This post posted at this site is
    in fact good.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: