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

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
  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

How the BigDecimal Class Helps Java Get its Arithmetic Right - How to use BigDecimal arithmetic in the Invoice application
(Page 4 of 4 )

Figure 4 shows how you can use BigDecimal arithmetic in the Invoice application. To start, look at the console output when BigDecimal is used. As you can see, this solves both the rounding problem and the floating-point problem so it now works the way you want it to.

To use BigDecimal arithmetic in the Invoice application, you start by coding an import statement that imports all of the classes and enumerations of the java.math package. This includes both the BigDecimal class and the RoundingMode enumeration. Then, you use the constructors and methods of the BigDecimal class to create the BigDecimal objects, do the calculations, and round the results when necessary.

In this figure, the code starts by constructing BigDecimal objects from the subtotal and discountPercent variables, which are double types. To avoid conversion problems, though, the toString method of the Double class is used to convert the subtotal and discountPercent values to strings that are used in the BigDecimal constructors.

Since the user may enter subtotal values that contain more than two decimal places, the setScale method is used to round the subtotal entry after it has been converted to a BigDecimal object. However, since the discountPercent variable only contains two decimal places, it isnít rounded. From this point on, all of the numbers are stored as BigDecimal objects and all of the calculations are done with BigDecimal methods.

In the statements that follow, only discount amount and sales tax need to be rounded. Thatís because theyíre calculated using multiplication, which can result in extra decimal places. In contrast, the other numbers (total before tax and total) donít need to be rounded because theyíre calculated using subtraction and addition. Once the calculations and rounding are done, you can safely use the NumberFormat objects and methods to format the BigDecimal objects for display.

When working with BigDecimal objects, you may sometimes need to create one BigDecimal object from another BigDecimal object. However, you canít supply a BigDecimal object to the constructor of the BigDecimal class. Instead, you need to call the toString method from the BigDecimal object to convert the BigDecimal object to a String object. Then, you can pass that String object as the argument of the constructor as illustrated by the last statement in this figure.

Is this a lot of work just to do simple business arithmetic? Relative to some other languages, you would have to say that it is. In fact, itís fair to say that this is a weakness of Java when it is compared to languages that provide a decimal data type. Once you get the hang of working with the BigDecimal class, though, you should be able to solve all of your floating-point and rounding problems with relative ease.

The Invoice application output when BigDecimal arithmetic is used

Figure 4.   How to use BigDecimal arithmetic in the Invoice application

The import statement thatís required for BigDecimal arithmetic

  import java.math.*; // imports all classes and enumerations in java.math

The code for using BigDecimal arithmetic in the Invoice application

  // convert subtotal and discount percent to BigDecimal
  BigDecimal decimalSubtotal = new BigDecimal(Double.toString(subtotal));
  decimalSubtotal = decimalSubtotal.setScale(2, RoundingMode.HALF_UP);
  BigDecimal decimalDiscountPercent =
      new BigDecimal(Double.toString(discountPercent));
// calculate discount amount
  BigDecimal discountAmount =
  discountAmount = discountAmount.setScale(2, RoundingMode.HALF_UP);
// calculate total before tax, sales tax, and total
  BigDecimal totalBeforeTax = decimalSubtotal.subtract(discountAmount);
  BigDecimal salesTaxPercent = new BigDecimal(".05");
  BigDecimal salesTax = salesTaxPercent.multiply(totalBeforeTax);
  salesTax = salesTax.setScale(2, RoundingMode.HALF_UP);
  BigDecimal total = totalBeforeTax.add(salesTax);

How to create a BigDecimal object from another BigDecimal object

  BigDecimal total2 = new BigDecimal(total.toString());

  • With this code, all of the result values are stored in BigDecimal objects, and all of the results have two decimal places that have been rounded correctly when needed.
  • Once the results have been calculated, you can use the NumberFormat methods to format the values in the BigDecimal objects without any fear of rounding problems. However, the methods of the NumberFormat object limits the results to 16 significant digits.



If you havenít used the BigDecimal class before, I hope this article has demonstrated the need for it and will get you started using it. Also, if you like this article and our ďpaired pagesĒ presentation method, I hope it will encourage you to review our Java 5 book or some of our other books.

Unlike many Java books, Murachís Beginning Java 2, JDK 5 is designed to teach you the essential skills for developing business applications. Thatís why it shows you how to use the BigDecimal class, which isnít even mentioned in many competing books. Thatís also why it shows you how to do data validation at a professional level and how to develop three-tier database applications, two more essentials that are commonly omitted or neglected in competing books.

DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

blog comments powered by Disqus

- 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 

Developer Shed Affiliates


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