January 2003 Technical Tip Decimal Arithmetic You Can Trust

Last month we looked at two sample programs which demonstrated the imprecision inherent in the use of doubles. At that time we promised a solution. This imprecision occurs with doubles and (worse) floats, but never with integers. So one workaround is to use integer arithmetic. While this solution may seem somewhat unwieldy, this low-level thinking is what assembler programmers have been doing for decades!

You must keep in mind three key points:

  • Integer arithmetic always yields an integer result. For example, 2147 / 100 = 21 (not 21.47)
  • The percent sign (%) is the modulus operator; that is, it yields the remainder of division. For example, 2147 % 100 = 47
  • You can create a String by concatenating the quotient, a decimal point, and the remainder. For example: (2147 / 100) + "." + (2147 % 100) = 21.47

So here is our corrected version of the mileage program. All doubles have been replaced with ints:

   public class Mileage2
   {
      public static void main(String[] args)
      {
         int begOdo = 523907;
         int endOdo = 525571;
         int miles = endOdo - begOdo;
         System.out.println("You drove " +
            (miles / 10) + "." + (miles % 10) + " miles.");
      }
   }

The output appears as follows:

   You drove 166.4 miles.

And here's the corrected version of the sales tax example. It's a little more complicated because we used multiplication:

   public class SalesTax2
   {
      public static void main(String[] args)
      {
         int beforeTax = 12345;
         int salesTaxRate = 65;
         int afterTax = beforeTax * (1000 + salesTaxRate);
         System.out.println( "After tax amount is " + 
            (afterTax / 100000) + "." + (afterTax % 100000));
      }
   }

The output appears as follows:

   After tax amount is 131.47425

You might argue that this is unnecessary because you can use the Math.round or DecimalFormat.format methods to print the rounded results, and that is true in these cases. But printing intermediate results with rounding, while accumulating intermediate results without rounding, can cause final results to appear in error.

Caliber Data Training is pleased to offer training in Java (and assembler!) programming. We have recently rewritten our Visualage Java course to use the Websphere Application Development suite. We hope you will consider us when deciding upon a training provider.


Go to the articles index. Written by Bill Qualls. Copyright © 2003 by Caliber Data Training 800.938.1222