0

So I've been starting to make a Cash Register program which will take in what the user is paying and how much the object costs. This will tell the user how much coins (Toonies, loonies, etc.) they'll get in return. Here's the part of the code that determines how much coins the user will get in return:

if(amountPayed >= amountToPay) {
    remainder = amountPayed - amountToPay;

    while(remainder > 0) {

        if(remainder >= 2) {
            toonies++;
            remainder = remainder - 2;
            System.out.println(remainder);
        }

        else if(remainder >= 1) {
            loonies++;
            remainder = remainder - 1;
            System.out.println(remainder);
        }

        else if(remainder >= 0.25) {
            quarters++;
            remainder = remainder - 0.25;
            System.out.println(remainder);
        }

        else if(remainder >= 0.1) {
            dimes++;
            remainder = remainder - 0.1;
            System.out.println(remainder);
        }

        else if(remainder >= 0.05) {
            nickels++;
            remainder = remainder - 0.05;
            System.out.println(remainder);
        }

        else if(remainder >= 0.01) {
            pennies++;
            remainder = remainder - 0.01;
            System.out.println(remainder);
        }

    }

I've been having a problem with getting the correct amount, the loop ended up being infinite. I thought to myself, this can't be true as I made sure that all the values would go through evenly.

I decided I should do some debugging so I made it output the remainder everytime it went through. Here's what I got:

18.01
16.01
14.010000000000002
12.010000000000002
10.010000000000002
8.010000000000002
6.010000000000002
4.010000000000002
2.0100000000000016
0.010000000000001563
1.5629858518551032E-15

This was very weird to me because the numbers I entered only went to the second decimal. I was subtracting the numbers from the remainder just fine. So what's my problem?

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Zachary Vincze
  • 427
  • 7
  • 24
  • What is the type of all the associated variables? – Balwinder Singh Oct 28 '15 at 22:41
  • 4
    It appears you are using `double` for your money amounts. `BigDecimal` with scale 2 would work much better. `double` is a form of base 2 scientific notation in which your numbers cannot be represented exactly, only to a very close approximation - fine for engineering, not so good for money. – Patricia Shanahan Oct 28 '15 at 22:41
  • @BalwinderSingh They are doubles. – Zachary Vincze Oct 28 '15 at 22:41
  • 1
    Consider using longs to represent values in pence (or equivalent unit) to avoid rounding issues – MikeJ Oct 28 '15 at 22:42
  • @PatriciaShanahan Could you explain why doubles weren't working very well in this situation? – Zachary Vincze Oct 28 '15 at 22:42
  • This is the problem with double precision -- check it here --- http://stackoverflow.com/questions/15625556/java-adding-and-subtracting-doubles-are-giving-strange-results. Use `BigDecimal` to remove these issues – Balwinder Singh Oct 28 '15 at 22:43
  • 2
    Because base-2. You can't represent 1/3 without recursion in decimal; binary numbers can't represent certain values because they have no ability to deal with numeric recursion; they truncate. – Makoto Oct 28 '15 at 22:44
  • @ZacharyVincze For example, the closest double to 18.01 is 18.010000000000001563194018672220408916473388671875 – Patricia Shanahan Oct 28 '15 at 22:45
  • Take a read here for more info: http://floating-point-gui.de – yshavit Oct 28 '15 at 22:56

0 Answers0