Skip to main content
  1. Posts/

Double Trouble (Don't use doubles for currency or accurate decimals)

·402 words·2 mins
Joe Erickson
Author
Joe Erickson
Senior software developer specializing in web development, AI, and helping others learn to code.
Table of Contents

This is an article that I wrote a few years ago that still applies today. It sounds very specific to Java, but it’s something you need to watch out for in any language.


Working with decimal numbers can be more complicated than it might seem. Many a Java programmer has been bitten by using doubles when calculating currency or another decimal value that relies on precision.

The problem
#

Let’s say that we need to calculate a customer’s bill. They used 80000.01 kWHs (big bill!) and we charge a dollar per kWH for this customer. To calculate that in cents, we just do:

double amount = 80000.01 * 100.0;

The answer we expect from this is 8000001. What we actually get, however, is 8000000.999999999! Why is this? Because doubles are inaccurate with large numbers. They just can’t handle the calculation. They are actually made to be fast, not accurate.

You see, the decimal number must first be converted into a binary number. Due to the way that works, it can be impossible to store that decimal number into a binary representation, Just like you can’t make ⅓ into a decimal number.

⅓ = 0.33333333333333333333333333333333...

The threes just never end! If you want to store that number somewhere, you’ll have to eventually cut it off somewhere, and that means you’ve lost your precision. It’ll be almost correct, but not quite.

If you’re not careful with this, you can start to drop cents and, with enough accounts being calculated this way, dropped cents will soon mean a dropped job. When doing large financial, with-real-money calculations, almost correct is not correct.

So what should we do?
#

The Java language has anticipated this and created an object that can handle decimal numbers accurately. That class is BigDecimal . Using BigDecimals, our previous example would look like this:

BigDecimal kWH = new BigDecimal("80000.01");
BigDecimal price = new BigDecimal("100.0");
BigDecimal amount = kWH.multiply(price);

More complicated but we get the right answer of 8000001.00. It’s important to create the BigDecimal with Strings so that we keep the numbers safe from being accidentally converted into doubles at any time. If we called this as new BigDecimal(80000.01); , the number would be translated as a double first and then a BigDecimal, and we’ll have the same problem we had before. We should avoid using double s at all when dealing with important decimal numbers.

Remember: BigDecimal, not double or Double!

Related

Don't fear the frustration

I’ve always been a little more tenacious than most people I know, willing to spend the time to flail before making the breakthrough that gets the results I’m looking for.1 I think part of that has to do with the fact that I do most of the flailing in private, at a computer where no one can point out my failures or see what I’m working on before it’s ready. But as I’ve taught other people programming over the years, I’m always surprised at how quickly they throw in the towel on problems that I know are solvable.

Ask Away: Judging Your Skills

I recently got an email from one of my tutoring students about how he had finished setting up an e-commerce site for his Dad’s salsa business, which was a pretty big accomplishment. But there were two things in the email that I took issue with. One was that he thought it was weird that another web dev shop had asked for $3,000 to set up a shopping cart in Spotify and the other was that he felt that using an off the shelf solution (BigCommerce) was a cop out and he should have been able to build it himself. I think everyone’s felt both those things at some point–I know I have–but I sent him this in response:

Security topics every web developer needs to know

·2344 words·12 mins
When it comes to web application security, there are a class of things that every web developer should know. Trust me, you need to learn these and you’ll use them on every project you do. Interviewers ask about this stuff, so learn about them and how to handle them in whatever language you’re using.