Java Tips & Tricks: Double Trouble
At work, we've got a lot of new Java developers starting and I thought it might be a good idea to start up a little newsletter that, each week, will give little tips that Java programmers need to know but aren't usually told in classes or books. This is the first.
Double Trouble
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.
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. We create the BigDecimal with Strings so that we keep the numbers safe from being rounded. 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 be passing it through an inaccurate format before getting it into a BigDecimal. We should avoid using doubles at all when dealing with important decimal numbers.
Remember: BigDecimal, not double or Double!