`BigDecimal`

Doesn't Belong in Real-World Applications^{©}Conrad Weisert

September 1, 2012

NOTE: This article may be reproduced and circulated freely, as long as the copyright credit is included.

Many Java experts recommend using Java's library class

whenever Java's built-in "primitive"
numeric data types provide insufficient precision. This occurs commonly,
for example, in dealing with amounts of
**BigDecimal****money**. a central part of financial applications. Even the highly respected
collection of advice from Joshua Bloch nudges the reader in
that direction. After showing an example in which floating-point representation of U.S. dollars
yields an incorrect result, the author advises:^{1}

If you run the program, you'll find that you . . . have $0.3999999999999999 left. This is the
wrong answer! The right way to solve this problem is to use | An alternative to using |

and David Flanagan explains:^{2}

Because it uses a decimal rather than binary floating-point representations, it is
not subject to rounding errors that |

No, no, no! Why do experts keep forgetting that Java is an object oriented
programming language and books about Java are supposed to be about *object-oriented* programming?

If we examine typical uses of

it turns out that
very few of them actually need a numeric representation
that's unusually **BigDecimal***big*. They're just using the *decimal scaling* capability to mimic what
they might have specified in PL/I as

or
in COBOL as **FIXED DECIMAL(9,2)**

. The ability to handle
monstrously long numbers in **PICTURE S9(7)V99**

just imposes
unnecessary complexity and inefficiency.
**BigDecimal**

Joshua Bloch had the right idea when he suggested, as an alternative, using

to represent amounts of money—but not about
"keeping track of the decimal point yourself". The obvious choice for representing
amounts of money is to use a **long**

class, such as the one
on this web site. The **Money**

class has to keep track of
the scaling, of course, but applications that use it just use the familiar units of the currency they're
working with.
**Money**

In fact the internal (hidden member) data can be either

or **long**

, in integer units of the smallest increment (e.g. U.S.
¢) but certainly not **double**

.
So, if **BigDecimal**

is unsuitable for amounts of money, what is
it good for? So far, we haven't encountered any practical use for it in a real business or
scientific application.
**BigDecimal**

`BigInteger`

?Java textbooks often present

and **BigDecimal**

together as if there were some relationship between them. However, they're entirely different, both
in their internal workings and in the range of problems they're designed to solve.
**BigInteger**

A

(64-bit) integer can represent numbers between
±2**long**^{63} or roughly 10^{20}.
Since this magnitude approaches the number of atoms in the universe, it's extremely unlikely
that any data type with a unit of measure would require values having a greater magnitude.
In particular, financial applications, despite serious inflation, are not called upon to
manipulate quintillions of dollars.

If we don't need

for data having a unit of measure
or for typical business or scientific applications, what good is it? It can be very useful in dealing
with **BigInteger***pure numbers*, in such areas as:

- number theory research and
- cryptography.

^{1}—*Effective Java*, second edition, Addison-Wesley, ISBN 978-0-321-35668-0, p. 219.
^{2}—*Java in a Nutshell*, fifth edition, O'Reilly, ISBN 978-0-596-00773-7, p. 543.

Last modified December, 2014