Working with Java's BigDecimal 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:

double price = … double discount = … price -= discount;

and subsequently write this:

BigDecimal price = … BigDecimal discount = … price.subtract(discount);

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:

Decimal total = new Decimal("106838.81"); Decimal a = new Decimal("263970.96"); BigDecimal b = new BigDecimal("879.35"); Decimal c = new Decimal("366790.80"); total.add(a); total.subtract(b); total.subtract(c); System.out.println(total.toString());

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.

Happy coding!

EJB