Once and for all: Do not use double for money

The discussion on how to represent money in applications pops up regularly . Funny lots of people still use double to represent money. During my interviews some people use double for money. Once and for all: Do not use double. Double cannot represent all amounts of money and it has rounding problems. Use a Money class. Represent the amount with a BigDecimal in cents and use BigDecimal.ROUND_HALF_EVEN as your rounding method. Use a distribute algorithm to distribute money to severel slots without losing cents.

Read more about a money class from Martin Fowler or this TSS discussion. Anders writes about Money in .NET.

Rant off. Thanks for not using double anymore.


11 Responses to “Once and for all: Do not use double for money”  

  1. Gravatar Icon 1 digital.alterego

    What do you mean with “Use a distribute algorithm to distribute money to severel slots without loosing cents.”? Could you please explain this further? Anyway thanks for the links, good discussions there.

  2. Gravatar Icon 2 stephan

    @digital.alterego: Fowler calls it allocate I guess. You have 3 people and need to distribute (allocate) 10 EUR to them. 10/3 = 3.33 in cents, which means 1 cent is lost. Distributing 10 EUR correctly will result in 3 buckets [3.33, 3.33, 3.34].

  3. Gravatar Icon 3 Eric Burke

    I always distribute as [3.33, 3.33, 3.33] and then deposit 0.01 into my own secret account.

  4. Gravatar Icon 4 stephan

    The comic hero, I´m really honoured.

    A lot of people tried this, most of them got caught when getting greedy :-)

  5. Gravatar Icon 5 Greg Miller

    Quote:
    ————————–
    I always distribute as [3.33, 3.33, 3.33] and then deposit 0.01 into my own secret account.
    ————————–

    Just make sure you don’t mess up on some mundane detail like putting a decimal point in the wrong place.

    But seriously, it’s been my opinion for a while that using float or double should cause a compiler warning optionally suppressed by a compiler flag. I believe the only place a typical programmer would run into floats being used correctly would be 3D graphics programming.

  6. Gravatar Icon 6 stephan

    @Greg: I have the same feeling. Developers using double or float do use the wrong type in most cases except for 3D graphics or statistics.

  7. Gravatar Icon 7 FEZ

    I don’t know about USA, but in Europe you would use ROUND_HALF_UP for money rounding!?

  8. Gravatar Icon 8 stephan

    ROUND_HALF_EVEN is called fair rounding because it distributes the error. It’s also called bankers rounding.

    http://en.wikipedia.org/wiki/Rounding#Round-to-even_method

    “Rounding mode to round towards the “nearest neighbor” unless both neighbors are equidistant, in which case, round towards the even neighbor. Behaves as for ROUND_HALF_UP if the digit to the left of the discarded fraction is odd; behaves as for ROUND_HALF_DOWN if it’s even. Note that this is the rounding mode that minimizes cumulative error when applied repeatedly over a sequence of calculations.”

    http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigDecimal.html#ROUND_HALF_EVEN

  9. Gravatar Icon 9 FEZ

    http://en.wikipedia.org/wiki/Rounding#Round-to-even_method:

    “The origin of the term bankers’ rounding is more obscure. If this rounding method was ever a standard in banking, the evidence has proved extremely difficult to find. To the contrary, section 2 of the European Commission report The Introduction of the Euro and the Rounding of Currency Amounts [2] suggests that there had previously been no standard approach to rounding in banking.”

  1. 1 Finds of the Week - December 13, 2008 » Chinh Do
  2. 2 BigDecimal money cookbook at Stephans Blog


Leave a Reply



RSS