Eric Bruno

Dr. Dobb's Bloggers

Working with Java's BigDecimal

August 12, 2014

I've found BigDecimal a bit harder to use than either Java's double primitive type or Double class.

In my previous blog, we discussed how important it is to avoid using Java's primitive float or double types when performing currency calculations within applications such as financial applications. Instead, BigDecimal provides the scaling and rounding needed to control the precision of floating-point arithmetic.

However, I've found BigDecimal a bit harder to use than either Java's double primitive type or Double class (which is really just a wrapper for double). For instance, given that it's an immutable object, calling methods such as add or subtract has no lasting effect on the object you call it on. Instead, it returns a new BigDecimal object that you need to store or reassign. If you're used to using primitive types or their wrapper classes to modify values like this:

you'll likely have a bug because your discount won't be applied. You need to reassign the result:

price = price.subtract(discount);

Not only can this be error-prone, it's also quite verbose. Even the class name BigDecimal is tedious to type. To help in my coding, I've created a wrapper class that contains a BigDecimal object internally  much like the Double class contains a double value  but instead handles the reassignment of the immutable BigDecimal on your behalf. I also call it (for better or worse) Decimal, since I find it easier to type. You can download the code for the Decimal class to take a look.

To use it, you create a Decimal object using one of the contructors identical to those of the BigDecimal class (see below for an example). Then, you can simply call any of the modifier methods without worry of reassignment. In fact, methods such as add, subtract, multiply, and divide purposely don't return anything just to reinforce this point, but you can modify this wrapper class to return the value if you desire. Here's an example:

which, by the way, returns the result "3139.62". Other methods work the same way. For instance:

total.negate();
System.out.println(total.toString());

Returns the result "-3139.62". Internally, methods such as add, and so on, are implemented like this:

public void add(Decimal dec) {
bd = bd.add( dec.getBigDecimal() );
}

However, not all methods have side-effects like this. Methods such as abs, min, max, remainder and a few others simply return new a Decimal or BigDecimal object. The choices here should be obvious (you probably don't want to reassign your original BigDecimal value when calling a method to get its absolute value), but you can modify this class if you don't agree with my decisions. Overall, I hope you find this BigDecimal wrapper class useful.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!