0

I want to make a little system that returns me the optimized quantity of bills and coins for any value.

Here's my code for while:

public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(
            new InputStreamReader(System.in));
    double amount = Double.parseDouble(br.readLine());
    if (amount > 0 && amount < 1000000.00) {
        // ############################# BILLS ############################
        double rest100 = amount / 100;
        double rest50 = amount % 100;
        double rest20 = rest50 % 50;
        double rest10 = rest20 % 20;
        double rest5 = rest10 % 10;
        double rest2 = rest5 % 5;

        // ############################ COINS ############################            
        double rest01 = rest2 % 2;
        double rest050 = rest01 % 1;
        double rest025 = rest050 % .5;
        double rest010 = rest025 % 25;
        double rest005 = rest010 % .1;
        double rest001 = rest005 % .05;

        System.out.println("BILLS:\n"
            + (int) rest100
            + " bill(s) of 100.00\n"
            + (int) rest50 / 50
            + " bill(s) of 50.00\n"
            + (int) rest20 / 20
            + " bill(s) of 20.00\n"
            + (int) rest10 / 10
            + " bill(s) of 10.00\n"
            + (int) rest5 / 5
            + " bill(s) of 5.00\n"
            + (int) rest2 / 2
            + " bill(s) of 2.00\n"
            + "COINS:\n"
            + (int) (rest01 / 1)
            + " coin(s) of 1.00\n"
            + (int) (rest050 / .5)
            + " coin(s) of 0.50\n"
            + (int) (rest025 / .25)
            + " coin(s) of 0.25\n"
            + (int) (rest010 / .1)
            + " coin(s) of 0.10\n"
            + (int) (rest005 / .05)
            + " coin(s) of 0.05\n"
            + (int) (rest001 / .01)
            + " coin(s) of 0.01");
    }
}

Well, it's almost correct, the bills are working perfect, my problem is with the coins.

Here are some inputs:

  • 576.73 // Print correctly
  • 8.45 // Print incorrectly
  • 9.45 // Print incorrectly, look below:

Actual output:

BILLS:
0 bill(s) of 100.00
0 bill(s) of 50.00
0 bill(s) of 20.00
0 bill(s) of 10.00
1 bill(s) of 5.00
2 bill(s) of 2.00
COINS:
0 coin(s) of 1.00
0 coin(s) of 0.50
1 coin(s) of 0.25
4 coin(s) of 0.10
0 coin(s) of 0.05
4 coin(s) of 0.01

Expected output:

BILLS:
0 bill(s) of 100.00
0 bill(s) of 50.00
0 bill(s) of 20.00
0 bill(s) of 10.00
1 bill(s) of 5.00
2 bill(s) of 2.00
COINS:
0 coin(s) of 1.00
0 coin(s) of 0.50
1 coin(s) of 0.25
2 coin(s) of 0.10
0 coin(s) of 0.05
0 coin(s) of 0.01

PS: I won't post all the expected outputs because it will let the question bigger than now, BUT if you need, I can post. Thanks in advance.

developer033
  • 24,267
  • 8
  • 82
  • 108
  • 2
    I suspect the problem lies in 0.1, 0.05, and 0.01 as they cannot be precisely represented as a floating point number. Consider using integer for this kind of problem as integer operations are precise and fast. – Dafang Cao Apr 15 '16 at 02:26
  • Whay are you using math.floor(rest100): ? And why do you have a 50 cent coin? – kpie Apr 15 '16 at 02:27
  • 1
    @kpie really for nothing.. a mistake, but it doesn't matter (unfortunately). The 50 cent coin exists in my country. – developer033 Apr 15 '16 at 02:30
  • Please do post an example of an invalid output for those of us who are too busy to run your code. – meriton Apr 15 '16 at 02:36
  • Correct this line `double rest010 = rest025 % .25;` (missing decimal point before .25). Also, doing modulo arithmetic (`%` operator) with double may give erroneous results because of imprecision (for example, 8.45 prints `4 coin(s) of 0.01`). – Sci Prog Apr 15 '16 at 02:39
  • @meriton done. Sci Prog Thanks for the correction. What can I do to correct this imprecision? – developer033 Apr 15 '16 at 02:45
  • The imprecision is inherent to the way floating point numbers are stored in a computer. For example, see http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html That is why @kpie suggested to multiply numbers by 100 (I added: and use integers). – Sci Prog Apr 15 '16 at 02:51

2 Answers2

1

Just multiply by 100 and do the calculations in cents.

kpie
  • 9,588
  • 5
  • 28
  • 50
  • 1
    I upvoted your answer (even if others did not see the reason): I would avoid modulo arithmetic with floating point numbers, because of rounding errors. Multiply by 100, and use integers. – Sci Prog Apr 15 '16 at 02:45
0

The following version of code will work as per your requirements. Avoid using double in modulus operation.

CODE:

public static void main(String[] args) throws NumberFormatException, IOException {
    BufferedReader br = new BufferedReader(
            new InputStreamReader(System.in));
    double amount = Double.parseDouble(br.readLine());
    amount= Math.round(amount*100);     
    if (amount > 0 && amount < 1000000.00) {            
        // ############################# BILLS ############################
        double rest100 = amount / 10000;
        double rest50 = amount % 10000;
        double rest20 = rest50 % 5000;
        double rest10 = rest20 % 2000;
        double rest5 = rest10 % 1000;
        double rest2 = rest5 % 500;

        // ############################ COINS ############################            
        double rest01 = rest2 % 200;
        double rest050 = rest01 % 100;
        double rest025 = rest050 % 50;
        double rest010 = rest025 % 25;
        double rest005 = rest010 % 10;
        double rest001 = rest005 % 5;

        System.out.println("BILLS:\n"
            + (int) Math.floor(rest100)
            + " bill(s) of 100.00\n"
            + (int) (rest50 / 5000)
            + " bill(s) of 50.00\n"
            + (int) (rest20 / 2000)
            + " bill(s) of 20.00\n"
            + (int) (rest10 / 1000)
            + " bill(s) of 10.00\n"
            + (int) (rest5 / 500)
            + " bill(s) of 5.00\n"
            + (int) (rest2 / 200)
            + " bill(s) of 2.00\n"
            + "COINS:\n"
            + (int) (rest01 / 100)
            + " coin(s) of 1.00\n"
            + (int) (rest050 / 50)
            + " coin(s) of 0.50\n"
            + (int) (rest025 / 25)
            + " coin(s) of 0.25\n"
            + (int) (rest010 / 10)
            + " coin(s) of 0.10\n"
            + (int) (rest005 / 5)
            + " coin(s) of 0.05\n"
            + (int) (rest001 / 1)
            + " coin(s) of 0.01");
    }

OUTPUT:

9.45
BILLS:
0 bill(s) of 100.00
0 bill(s) of 50.00
0 bill(s) of 20.00
0 bill(s) of 10.00
1 bill(s) of 5.00
2 bill(s) of 2.00
COINS:
0 coin(s) of 1.00
0 coin(s) of 0.50
1 coin(s) of 0.25
2 coin(s) of 0.10
0 coin(s) of 0.05
0 coin(s) of 0.01
Sajeev
  • 818
  • 7
  • 23