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

- 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