0

we are doing a small project in school and we have the following problem. A user inputs an amount of how much a busticket costs, in this case - 2.10. The number of tickets has to also be inputted in this case 1. Afterwards the user inputs how much money he is going to give betwee 50c and 2Euro. I input 2 euro twice. The Change is then calculated. However when inputting these particular numbers instead of getting the anser 1.90, I get 1.85.

import java.util.Scanner;

class Fahrkartenautomat {
    public static void main(String[] args) {

        Scanner tastatur = new Scanner(System.in);

        double amountToPay;
        double depositetTotalAmount;
        double insertionofCoins;
        double Change;
        double stillToPay;
        double ticketPrice;
        int numberOfTickets;

        // Geldbetrag eingeben
        System.out.print("Ticketpreis (Euro): ");
        ticketPrice = tastatur.nextDouble();
        System.out.print("Anzahl der Tickets: ");
        numberOfTickets = tastatur.nextInt();
        amountToPay = ticketPrice * numberOfTickets;
       



        // Geldeinwurf
        depositedTotalAmount = 0.0;
        stillToPay = 0.0;
        while (depositedTotalAmount < amountToPay) {
            stillToPay = amountToPay - depositedTotalAmount;
            System.out.print("Noch zu zahlen: ");
            System.out.printf("%.2f", nochZuZahlen);
            System.out.println(" Euro");
            System.out.print("Eingabe (mind. 5 Cent, höchstens 2 Euro): ");
            insertionOfCoins = tastatur.nextDouble();
            depositedTotalAmount = depositedTotalAmount + insertionOfCoins;
        }

        // Fahrscheinausgabe
        System.out.println("\nFahrschein wird ausgegeben");
        for (int i = 0; i < 8; i++) {
            System.out.print("=");
            try {
                Thread.sleep(200);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("\n\n");

        
        Change = depositedTotalAmount - amountToPay;
        if (Change > 0.0) {
            System.out.print("Der Rückgabebetrag in Höhe von ");
            System.out.printf("%.2f", Change);
            System.out.println(" Euro");
            System.out.println("wird in folgenden Münzen ausgezahlt:");

            while (Change >= 2.00) { // 2-Euro-Münzen
                System.out.println("2 Euro");
                Change = Change - 2.00;
            }
            while (Change >= 1.00) { // 1-Euro-Münzen
                System.out.println("1 Euro");
                Change = Change - 1.00;
            }
            while (rueckgabebetrag >= 0.50) { // 50-Cent-Münzen
                System.out.println("50 Cent");
                Change = Change - 0.50;
            }
            while (Change >= 0.20) { // 20-Cent-Münzen
                System.out.println("20 Cent");
                Change = Change - 0.20;
            }
            while (rueckgabebetrag >= 0.10) { // 10-Cent-Münzen
                System.out.println("10 Cent");
                Change = Change - 0.10;
            }
            while (Change >= 0.05) { // 5-Cent-Münzen
                System.out.println("5 Cent");
                Change = Change - 0.05;
            }
        }

        System.out.println("\nVergessen Sie nicht, den Fahrschein\n" + "vor Fahrtantritt entwerten zu lassen!\n"
                + "Wir wünschen Ihnen eine gute Fahrt.");

        tastatur.close();
    }
}
  • 1
    Please, first make sure your code actually compiles. Because as it looks there are some typos (e.g. `depositetTotalAmount` and `depositedTotalAmount`, `Change` vs `rueckgabebetrag`) which make the current code not compile. Seems like you tried to translate some variables but stopped midway. Then, add your input, actual output and expected output to your question. – maloomeister Oct 18 '22 at 09:23
  • 2
    It seems you're mixing variables: `while (Change >= 1.00)` is followed by `while (rueckgabebetrag >= 0.50)`. Also please note that you'll make your life easier if you stick to the Java conde conventions which means `change` instead of `Change` etc. – Thomas Oct 18 '22 at 09:25
  • 1
    Hint: Print your `change` variable after each subtraction. What do you see? -> [Why not use Double or Float to represent currency?](https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency) – maloomeister Oct 18 '22 at 09:28
  • Btw, do you already get `"Der Rückgabebetrag in Höhe von 1.85 Euro wird in folgenden Münzen ausgezahlt"` when you enter a ticket price of 2.10, number of tickets 1 and 2x 2 for the payment? Or does it print "... 1.90 Euro..." along with individual coins that add up to only 1.85? – Thomas Oct 18 '22 at 09:32
  • @Thomas the latter is the case. – maloomeister Oct 18 '22 at 09:34
  • @maloomeister I see, in that case I'd like to double upvote your comment on precision – Thomas Oct 18 '22 at 09:38
  • 1
    Floating point is a poor choice for currency because it is imprecise. Only work with integer numbers of cents. So total 210 for the ticket, notes and coins with values 200, 100, 50, 20, 10, 5 etc. after changing to that, everything should be easier and you won't suffer from inaccurate subtractions of floating point numbers. – Bohemian Oct 18 '22 at 10:02

1 Answers1

0

Your problem is with floating-point arithmetic. Computers do not perform calculations same as humans do. For monetary applications you would be better of using BigDecimal rather than double or you can round the Change parameter in each step which is sufficient in your case.
Below is the output of your code with Change parameter exposed:

Der Rückgabebetrag in Höhe von 1.90 Euro
wird in folgenden Münzen ausgezahlt:
Change: 1.9
1 Euro
Change: 0.8999999999999999
50 Cent
Change: 0.3999999999999999
20 Cent
Change: 0.1999999999999999
10 Cent
5

As you can see calculation is not exact, therefore avoiding your conditions.

Further advice:

  1. camelCase for variables is common practice for java.
  2. I understand that you translated your code for help. You would be better of writing your code in english from the start.
  3. I would prefer a switch statement or else if blocks in while loop for the change part if I were you.
    Happy coding!