| |||||||||
Java Traps: Big Decimal
Java Traps: Big DecimalFortunately, it's now almost common sense for programmers not to use the simple typesfloat's and double's for representing monetary values
(or any other value preferably :-)
due to the impression surrounded with these types. float's and double's are further restricted by a fixed set of bits to represent
them, hence only a limited set of numbers can be held in these types. Armed with this knowledge, fun code examples can be produced such as
the one from bytes.com
// Bill Gates has 100,000,000,000 in his savings account. His bank's
// statement is printed using:
#include <stdio.h>
int main(void) {
float y = 1e11F;
printf("Your balance is %.2f\n", y);
return 0;
}
// The bank's computer prints the result as:
Your balance is 99999997952.00
Yes it's C code not Java, but fun never the less. The salvation seems to be the java.math.BigDecimal class as it has not only precision
but is not represented by a fixed set of bits. Let's have some fun comparing its performance to double and discover some of the traps that
lay in store for you the first time you use BigDecimal.
PrintingThis one struck me and some co-workers when we had to convert some numbers to and from XML in a low-level fashion. First let's revisit thedouble and see how it performs when printing
double d1 = 2.2; double d2 = 2.3; System.out.println(d1 + d2); >> 4.5Now lets try the same with a BigDecimal
double d1 = 2.2; double d2 = 2.3; System.out.println(new BigDecimal(d1)); System.out.println(new BigDecimal(d2)); >> 2.20000000000000017763568394002504646778106689453125 >> 2.29999999999999982236431605997495353221893310546875While XML in itself is not very pleasant, these numbers surely shouldn't make it to any front-end (yes you guessed it, the XML was for web services!). The numbers do not very accurate either. Any accountant would be shaking in his pants, should he see this code example! Notice the random nature of the numbers. Seemingly d1 > 2.2 while d2 < 2.3. This is due to the (imprecise) internal representation
of doubles in the JVM as documented in Java Double trap. Let's have some fun adding the two numbers together...
System.out.println(new BigDecimal(d1).add(new BigDecimal(d2))); >> 4.50000000000000000000000000000000000000000000000000The addition actually came out nicely.. well, except for the number of digits displayed is. Especially considering the result 4.5
we got from out calculation using double...
SolutionThere are ways to avoid the problem.
System.out.println(new BigDecimal("" + d1));
System.out.println(new BigDecimal("" + d2));
System.out.println(new BigDecimal("" + d1).add(new BigDecimal("" + d2)));
System.out.println(new BigDecimal(d1).add(new BigDecimal(d2)).doubleValue());
>> 2.2
>> 2.3
>> 4.5
>> 4.5
Voula! Curious readers should seek more more info on
javadoc BigDecimal
MathAnother trap you quickly realize is that you can't use+, - etc since you are operating on objects. Hence, to add numbers you
must turn to the add() method. For good reasons (memory usage) add() in BigDecimal was the first add() method I've
encountered in the Java API which behaves differently to all other add()'s so be careful ;-)
BigDecimal bd = new BigDecimal("2.3");
bd.add( new BigDecimal("2.3") );
System.out.println(bd);
>> 2.3
Adding a number does not change the state of the object referenced by the bd reference.
SolutionInstead a new object is returned. Hence we have to say
BigDecimal bd = new BigDecimal("2.3");
bd = bd.add( new BigDecimal("2.3") );
System.out.println(bd);
>> 4.6
JDK1.4.2 and 1.5 differencesAs documented by Joseph D. Darcy in his quality blog, significant changes has been made to BigDecimal across version 1.4.2 and 1.5. The details are beyon the scope of this article, so I'll recommend interested audience to give it a click. That's all for this time. If you've been trapped in other ways using theBigDecimal api, please let me know and I'll extend this section...
Have fun...
CommentsIf you have any comments to this article, please drop me a mail at firstclassthoughts at gmail dot com please indicate if I can't publish whole or parts of your comment on the site.If you like this site consider Help spread the wordShare this post on your favorite social bookmarking sites:
The most recent contributions 20/05/09 Board Game Jungle speed / Arriba Review of the cool game "Jungle Speed" aka. "Arriba". 16/05/09 Danish Twin words "Twin words" are words that not only have multiple meanings, they must be composed next to each other in meaningful sentences. This article explores the concept of twin words. 14/05/09 English Twin words "Twin words" are words that not only have multiple meanings, they must be composed next to each other in meaningful sentences. This article explores the concept of twin words. 04/05/09 'Office space' extras Crazy stuff about the funny movie "Office space". Nothing of interest? Try browsing the entire article archive... | |||||||||