-3

Does anyone have an idea where my output problem is?

I have written a Java program, and run it on VM on Mac lion with Eclipse. Instead of getting 1.41, I got 1.4100000000000001 on my machine.

Example:
Enter the number of quarter: 4
Enter the number of dimes: 3
Enter the number of nickels: 2
Enter the number of pennies: 1

Total $1.4100000000000001

Example: 
Enter the number of quarter: 3
Enter the number of dimes: 2
Enter the number of nickels: 1
Enter the number of pennies: 6

Total $1.06

Example:
Enter the number of quarter: 5
Enter the number of dimes: 7
Enter the number of nickels: 4
Enter the number of pennies: 4

Total $2.1900000000000004

It appears sometimes the outputs are correct while other times have an issue.

Code:

import java.util.*;

public class CountChange
{
    public static void main(String[]args)
    {   
        Scanner inputScanner = new Scanner(System.in);
        System.out.print("Enter the number of quarters: ");
        int quarters = inputScanner.nextInt();
        System.out.print("Enter the number of dimes: ");
        int dimes = inputScanner.nextInt();
        System.out.print("Enter the number of nickles: ");
        int nickles = inputScanner.nextInt();
        System.out.print("Enter the number of pennies: ");
        int pennies = inputScanner.nextInt();
        inputScanner.close();

        double total =0.00;
        total = quarters * 0.25 + dimes * 0.1 + nickles * 0.05 + pennies * 0.01;

        System.out.println("Total $" + total);
        System.out.print("Thank you");
    }
}
rgettman
  • 176,041
  • 30
  • 275
  • 357
user2844217
  • 1
  • 1
  • 1
  • 2

3 Answers3

2

Your problem is related to how floating point (put easily, float/double related calculations) take place. Floating point numbers are an approximate reperesentation (if you are interested in the theory behind, the standard is IEEE754). Here you are getting exactly that, an approximate representation.

Since you are handling money, which goes only to cents (you cannot have 0.0001$ in currency), I suggest representing values with int (or long, or any integer type) values as cents. Then, divide by 100 when showing the result.

Stefano Sanfilippo
  • 32,265
  • 7
  • 79
  • 80
1

You have experienced the inexactness of representing floating-point numbers as doubles. The number 0.1 cannot be represented exactly in binary, so when you say 0.1 in Java, you get the closest possible approximation to 0.1. The same thing applies to 0.05 and 0.01.

There are a couple of things you can do:

  • Postpone floating-point arithmetic for as long as possible.

Example:

total = quarters * 25 + dimes * 10 + nickles * 5 + pennies;
total /= 100.0;

Example:

DecimalFormat df = new DecimalFormat("0.00");
System.out.println("Total $" + df.format(total));

Neither of these workarounds gets around the basic issue - the inexact representation of a number by a double. Especially for amounts of money, don't use double. You could even use a BigDecimal instead, whose precision is arbitrary.

rgettman
  • 176,041
  • 30
  • 275
  • 357
0

I agree with the explanations of why you are encountering this problem. My recommended solution for this sort of situation in Java is to use BigDecimal. It does exactly those calculations you would expect to be exact for short decimal fractions. For inexact calculations, it offers a good choice of rounding methods.

In effect, it does integer arithmetic with a scale factor, but automates storage and management of the scale.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75