Code Monkeyism

Programming is hard by Stephan Schmidt

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.

About the author: Stephan Schmidt is currently a team manager at ImmobilienScout24 in Berlin. Stephan has been working as a head of development and CTO. He has used a lot of different technologies in the last 20 years including Java, Rails and Python. Stephans main field of interest is maintainablity and productivity in software development. Want to know more? All views are only his own.

If you did like this article but you don't want to subscribe to new articles with your reader, you can follow me on Twitter or subscribe to new posts with your email:

Comments

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.

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].

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

stephan

The comic hero, I´m really honoured.

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

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.

[...] Stephan advised to use the "money" data type to store currency amounts instead of doubles. For good reasons. [...]

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.

FEZ

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

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

[...] No signal, no noise. « Once and for all: Do not use double for money [...]

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

Leave a Reply