Home arrow Java arrow 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: 4 stars4 stars4 stars4 stars4 stars / 9
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

TOOLS YOU CAN USE

advertisement
How the BigDecimal Class Helps Java Get its Arithmetic Right
(Page 1 of 4 )

When you use Java for simple business arithmetic, you may be surprised to discover that Java doesn’t always produce the right answers. If, for example, you use the double data type for an invoice’s subtotal, sales tax, and total, your arithmetic expressions may deliver inaccurate results. I’ll illustrate this in a moment.

The problem is that floating-point numbers can’t represent all decimal numbers with complete accuracy. Then, when you round the results to two decimal places, you can get errors. The best solution in a case like this is to use Java’s BigDecimal class, and that’s what you’ll learn to do in this document.

An Invoice application

To illustrate the math problems that are common when floating-point values are used for business applications, figure 1 presents a simple console application that calculates several values after the user enters an invoice subtotal. You can see the results for one user entry in this figure. This time, the arithmetic is correct.

The code for the application

Figure 1 also presents all of the Java code for this application. Here, the shaded code identifies the double values and arithmetic expressions that are used to do the math that this application requires. After those statements are executed, the results are given percent and currency formats, which round the results. Then, the results are displayed on the console.

You might notice that this application uses the new Scanner class that became available with Java 1.5. You might also notice that this application doesn’t provide for the exception that’s thrown if the user doesn’t enter a valid number at the console. Even in this simple form, though, the application will illustrate the math problems that are common with floating-point arithmetic.

The console for the formatted Invoice application


Figure 1.  An Invoice application that will illustrate some arithmetic problems

The code for the formatted Invoice application

import java.util.Scanner;
import java.text.NumberFormat;
public class InvoiceApp
{
    public static void main(String[] args)
    { 
        /
/ create a Scanner object and start while loop
        Scanner sc = new Scanner(System.in);
        String choice = "y";
        while (choice.equalsIgnoreCase("y"))
        {
           
// get the input from the user
            System.out.print("Enter subtotal: ");
             double subtotal = sc.nextDouble(); 
            
           
// calculate the results 
               double discountPercent = 0.0;
               if (subtotal >= 100)
                  discountPercent = .1;
               else
                  discountPercent = 0.0;
               double discountAmount = subtotal * discountPercent;
               double totalBeforeTax = subtotal – discountAmount;
               double salesTax = totalBeforeTax * .05;
               double total = totalBeforeTax + salesTax;
            
            // format and display the results
            NumberFormat currency = NumberFormat.getCurrencyInstance();
            NumberFormat percent = NumberFormat.getPercentInstance();
            String message =
                "Discount percent: " + percent.format(discountPercent) + "\n" 
              + "Discount amount: " + currency.format(discountAmount) + "\n"
              + "Total before tax: " + currency.format(totalBeforeTax) + "\n"
              + "Sales tax: " + currency.format(salesTax) + "\n"
              + "Invoice total: " + currency.format(total) + "\n";
            System.out.println(message);
            // see if the user wants to continue
            System.out.print("Continue? (y/n): ");
            choice = sc.next(); 
            System.out.println();
        }
    }
}


blog comments powered by Disqus
JAVA ARTICLES

- 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 ...
- Generics and Limitations in Java
- Getting Started with Java Web Development in...

Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 



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