0

I've been working on making a program to calculate change and the program never ends up running and terminating after completion. I don't know what's wrong with my code. If anyone could help that'd be great.

private static void calculateChange(double price, double given) {
    int ones = 0, quarters = 0, dimes = 0, nickels = 0, pennies = 0;
    double change = given - price;
    while (change != 0) {
        if (change >= 1) {
            change = change - 1;
            ones++;
        }
        if (change >= .25) {
            change = change - 0.25;
            quarters++;
        }
        if (change >= .10) {
            change = change - .10;
            dimes++;
        }
        if (change >= .05) {
            change = change - .05;
            nickels++;
        }
        if (change >= .01) {
            change = change - .01;
            pennies++;
        }
    }
    System.out.println();
    System.out.println("Correct Change");
    System.out.println("Ones " + ones);
    System.out.println("Quarters  " + quarters);
    System.out.println("Dimes " + dimes);
    System.out.println("Nickels " + nickels);
    System.out.println("Pennies " + pennies);

}
Asker123
  • 350
  • 1
  • 3
  • 15
  • Do not use floating point values for a program like this. Use integers (pennies) instead. – PaulMcKenzie Mar 04 '17 at 17:08
  • @PaulMcKenzie I've made the coins as Integers but it doesn't work. – Asker123 Mar 04 '17 at 17:09
  • Did you debug it? Change is probably becoming less than 0, which you're allowing. – Carcigenicate Mar 04 '17 at 17:09
  • @Asker123 When I say to use pennies, what I mean is to use pennies for everything. A dollar is 100, a quarter is 25, a nickel is 5, etc. So your calculations will not use `double` at all, instead it will be using purely integer arithmetic, which is exact (see the answers below). – PaulMcKenzie Mar 04 '17 at 17:12
  • @PaulMcKenzie Got it. But why does Java do this. Why does this happen with doubles and not ints? – Asker123 Mar 04 '17 at 17:14
  • 2
    @Asker123 [See this link and read it carefully](http://stackoverflow.com/questions/588004/is-floating-point-math-broken). This is a must for anyone wishing to be a computer programmer and has to deal with calculations like this. Money and financial calculations are in many instances required to compute exact values, thus using `double` for this is a definite no-go. – PaulMcKenzie Mar 04 '17 at 17:16
  • @PaulMcKenzie Good read. – Asker123 Mar 04 '17 at 17:21

3 Answers3

3

The double type is floating point, and floating point numbers trade precision for performance. At some point, when you are subtracting cents from change, it becomes less than 0.01 but greater than zero, or it becomes less than zero.

In either of these cases, all of your if conditionals will be false, but the while conditional still holds true, resulting in an infinite loop.

A quick solution would be to change your while condition from change != 0 to change >= 0.01.

A better solution would be to use an integral number type (such as int) and have it store the number of cents (so a dollar would be 100). This approach will not have any floating-point number inaccuracies.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • Got it. Thanks for that. I also made sure to add pennies++ because the change will always contain one less penny. – Asker123 Mar 04 '17 at 17:13
2

Numbers like 0.1, 0.05 or 0.01 cannot be represented exactly as binary floating point numbers. Therefore your change probably never becomes zero.

Aside from using integers or BCD, you could allow a tolerance when checking for zero, for example

while (Math.abs(change) < 0.000001) {
    ...
}
Frank Puffer
  • 8,135
  • 2
  • 20
  • 45
1

Perhaps this is a floating point issue. Your double precision "change" will never excactly equal integer zero, thus your "while" test will always evauate true. Try doing something along the lines of while(change >= epsilon)

Also... try using an if else-if chain...

IAS_LLC
  • 135
  • 11