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

About these ads

6 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

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 )

Twitter picture

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

Facebook photo

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

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 42 other followers

%d bloggers like this: