Home arrow Java arrow Page 2 - How the BigDecimal Class Helps Java Get its Arithmetic Right
JAVA

How the BigDecimal Class Helps Java Get its Arithmetic Right


If you use Java for simple business arithmetic, you might be seeing some errors. It's not your fault, it's a floating-point problem -- and this article explains how to use Java's BigDecimal class to fix it. It is excerpted from the book Murach's Beginning Java 2, JDK 5, written by Doug Lowe, Joel Murach, and Andrea Steelman (Murach Publishing, 2005; ISBN: 1890774294).

Author Info:
By: Murach Publishing
Rating: 5 stars5 stars5 stars5 stars5 stars / 13
February 02, 2006
TABLE OF CONTENTS:
  1. · How the BigDecimal Class Helps Java Get its Arithmetic Right
  2. · The math problems in the Invoice application
  3. · How to use the BigDecimal class
  4. · How to use BigDecimal arithmetic in the Invoice application

print this article
SEARCH DEVARTICLES

How the BigDecimal Class Helps Java Get its Arithmetic Right - The math problems in the Invoice application
(Page 2 of 4 )



The console at the top of figure 2 shows more output from the Invoice application in figure 1. But wait! The results for a subtotal entry of 100.05 donít add up. If the discount amount is $10.00, the total before tax should be $90.05, but itís $90.04. Similarly, the sales tax for a subtotal entry of .70 is shown as $0.03, so the invoice total should be $0.73, but itís shown as is $0.74. Whatís going on?

To analyze data problems like this, you can add debugging statements like the ones in this figure. These statements display the unformatted values of the result fields so you can see what they are before theyíre formatted and rounded. This is illustrated by the console at the bottom of this figure, which shows the results for the same entries as the ones in the console at the top of this figure.

If you look at the unformatted results for the first entry (100.05), you can easily see whatís going on. Because of the way NumberFormat rounding works, the discount amount value of 10.005 and the total before tax value of 90.045 arenít rounded up. However, the invoice total value of 94.54725 is rounded up. With this extra information, you know that everything is working the way itís supposed to, even though youíre not getting the results you want.

Now, if you look at the unformatted results for the second entry (.70), you can see another type of data problem. In this case, the sales tax is shown as .034999999999999996 when it should be .035. This happens because floating-point numbers arenít able to exactly represent some decimal fractions. As a result, the formatted value is $0.03 when it should be rounded up to $0.04. However, the unformatted invoice total is correctly represented as 0.735, which is rounded to a formatted $0.74. And here again, it looks like Java canít add.

Although trivial errors like these are acceptable in many applications, they are unacceptable in most business applications. And for those applications, you need to provide solutions that deliver the results that you want. (Imagine getting an invoice that didnít add up!)

One solution is to write your own code that does the rounding so you donít need to use the NumberFormat class to do the rounding for you. However, that still doesnít deal with the fact that some decimal fractions canít be accurately represented by floating-point numbers. To solve that problem as well as the other data problems, the best solution is to use the BigDecimal class that youíll learn about next.

Figure 2  The math problems in the Invoice application

Output data that illustrates a problem with the Invoice application

 

Statements that you can add to the program to help analyze this problem

  // debugging statements that display the unformatted fields
  // these are added before displaying the formatted results
  String debugMessage = "\nUNFORMATTED RESULTS\n"
                     
+ "Discount percent: " + discountPercent + "\n"
                      + "Discount amount:  " + discountAmount + "\n"
                      + "Total before tax:     " + totalBeforeTax + "\n"
                     
+ "Sales tax:    
" + salesTax + "\n"
                     
+ "Invoice total: " + total + "\n"
                      + "\nFORMATTED RESULTS";
System.out.println(debugMessage);

The unformatted and formatted output data

 


blog comments powered by Disqus
JAVA ARTICLES

- Java Too Insecure, Says Microsoft Researcher
- Google Beats Oracle in Java Ruling
- Deploying Multiple Java Applets as One
- Deploying Java Applets
- Understanding Deployment Frameworks
- Database Programming in Java Using JDBC
- Extension Interfaces and SAX
- Entities, Handlers and SAX
- Advanced SAX
- Conversions and Java Print Streams
- Formatters and Java Print Streams
- Java Print Streams
- Wildcards, Arrays, and Generics in Java
- Wildcards and Generic Methods in Java
- Finishing the Project: Java Web Development ...

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials