the blog for developers

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.

You can leave a Reply here. Of course, you should follow me on twitter here.

You can share this post!
Do you want to tell others about this article? Use the social bookmark icons to submit this artice to the service of your choice. Thanks.

About the author: Stephan Schmidt is head of development at brands4friends. He has more than 15 years of internet technology experience and 10 years experience in agile. He was head of development, consultant and CTO and is a speaker, author and blog writer. He specializes in organizing and optimizing software development helping companies by increasing productivity with lean software development and agile methodologies. Want to know more? All views are only his own.
Leave a reply.

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

Alex

funny enough, but Fowler did use double for money amount in his examples :-)

stephan

Alex: Sure?

Looking at page 491 of Patterns of Enterprise Application Architecture he explicitly discourages the use of floats and suggests using long (See google book search).

Ger

Today I came back to this posting. I’m maintaining an app made by other people no longer in the company, and there is an issue with money rounding – they used Double. I’m so pissed off I have to deal with this!!!
So yeah folks, I guess this posting is great advice.

Leave a Reply

What people wrote somewhere else:

Additional comments powered by BackType

Guide to CodeMonkeyism

Over the last 4 years I wrote many articles on this blog. To make it easier for you to find the relevant ones, I've organized them into topics.

Top 10

6 reasons why my VC funded startup did fail

Go Ahead: Next Generation Java Programming Style

Java Interview questions: Write a String Reverser

The dark side of NoSQL

7 Bad Signs not to Work for a Software Company or Startup

Is Java dead?

Scala vs. Clojure

Never, never, never use String in Java

No future for functional programming in 2008 – Scala, F# and Nu

Clojure vs Scala, Part 2

Java Developer

Is Java Dead?

Go Ahead: Next Generation Java Programming Style

Be careful with magical code

All variables in Java must be final

Never, never, never use String in Java

Bending Java: More readable code with methods that do nothing?

NoSQL Guy

NoSQL: The Dawn of Polyglot Persistence

The dark side of NoSQL

Essential storage tradeoff: Simple Reads vs. Simple Writes

Sharding destroys the goals of your relational database

The unholy legacy of databases

Startup/CTO

Development Dream Teams

6 reasons why my VC funded startup did fail

American vs. European style of Software Development

12 Things to Reduce Your Lead Time and Time to Market

The high cost of overhead when working in parallel

Essential storage tradeoff: Simple Reads vs. Simple Writes

Job Seeker

Another Good (Java) Interview Question

7 Bad Signs not to Work for a Software Company or Startup

Java Interview questions: Write a String Reverser (and use Recursion!)

Java Interview questions: Multiple Inheritance

As a Manager: What I value in developers

Top 10 Tips (+1) to Get a Pay Raise

Agilist

What Developers Need to Know About Agile

5 Practices Better to Change in Your Scrum Implementation

Scrum is not about engineering practices

ScrumMaster and ZenMaster: The joke of certification

What is Trans-Scrum?