0

I am currently writing a program that prints only the coins used when returning change. However, I get 2 assertions errors which are evaluated on the server's back-end. There are no sample test values, you have to make up your own.

expected:[...  Change Due $0.01  [1 penny] ]
but was:[...  Change Due $0.01  [2 pennies] ]
expected:[...  Change Due $0.19  [1 dime 1 nickel 4 pennies ]
but was:[...  Change Due $0.19  [2 dimes ]
/**
 * Calculate the amount of change based on user input.
 * Output coins with an output greater than 0. 
 * @param args returns an argument array for string objects
 */
public static void main(String[] args) {

    Scanner input = new Scanner(System.in);
    System.out.print("Total amount? ");
    double total = input.nextDouble();
    System.out.print("Cash payment? ");
    double payment = input.nextDouble();
    double changeDue = payment - total;

    System.out.println();
    System.out.printf("Change Due $%.2f\n\n", changeDue);

    int cents = (int) Math.ceil(changeDue * 100);
    int dollars = Math.round((int) cents / 100);
    cents = cents % 100;
    int quarters = Math.round((int) cents / 25);
    cents = cents % 25;
    int dimes = Math.round((int) cents / 10);
    cents = cents % 10;
    int nickels = Math.round((int) cents / 5);
    cents = cents % 5;
    int pennies = Math.round((int) cents / 1);

    int[] coins = {dollars,quarters,dimes,nickels,pennies};
    String[] names = {"dollar", "quarter", "dime", "nickel", "penny"};

    for (int i = 0; i < 5; i++) {
        if (coins[i] == 1) {
            System.out.println(coins[i] + " " + names[i]);
        } else if (coins[i] > 1 && i != 4) {
            System.out.println(coins[i] + " " + names[i] + "s");
        }
    }

    if (coins[4] > 1) {
        System.out.println(coins[4] + " pennies");
    }
}
Anil
  • 655
  • 1
  • 11
  • 25
Alexa Jenasoba
  • 93
  • 1
  • 1
  • 6

2 Answers2

0

Your code actually works fine. But the problem is if you just print your "changeDue" variable and see then you can see there is a 9 at the end. It is printed as 0.010000000000000009 not as 0.010000000000000000 as you would expect it to. Then it is ceiled as 2 after multiplying by 100. Then you get 2 pennies as the answer.

Actually this seems to be a problem with how decimals are stored. (Java Double value = 0.01 changes to 0.009999999999999787) It is explained here nicely. So you might have to change your approach a little bit.

Mahesh
  • 107
  • 5
  • This answer isn't wrong, but it isn't right either. You've answered the question, but I think it's at the wrong level of abstraction. You've told the poster what has gone wrong, but not how to move on and how to progress to a solution. the OP said, "help this egg is broken", and you said, "yes, eggshells respond to impact by shattering", when they actually needed someone to fetch them a cloth to clean it up with :) – Software Engineer Oct 06 '19 at 09:01
0

You have made a fairly common mistake in Java. Money cannot be represented by double, they are different things. In Java the closest thing we have to money is called BigDecimal. It's a little more awkward because you can't use arithmetic symbols with it (+-/*^%), but it's a lot more accurate.

There is also a formal specification for money: Money and Currency API (JSR 354), for which there are a couple of implementations including Joda Money and the offical reference implementation.

Software Engineer
  • 15,457
  • 7
  • 74
  • 102