Falsche Darstellung von Float

jopeter58

Mitglied
Hallo,
ich habe jetzt eine kleine Kaffeemaschine programmiert, welche über die Konsole läuft. Nun habe ich jedoch eine Frage. Wenn ich mein Programm ausführe und irgendein Programm wähle und einen Betrag kleiner als den Kaffeepreis eingebe und dann 0,01 €-Beträge eingebe, dann wird das Restgeld ganz komisch berechnet. Es wäre schön, wenn mir jemand erklären könnte, woran das liegt, denn wenn ich zum Beispiel Programm 1 gewählt habe, dann 0,50 € einwerfe, dann 0,01 €, 0,01€, 0,20€ und 0,05€, wird als Restbetrag 0.020000000000000018€ zurück gegeben. Warum ist das so? Könnte mir jemand sagen, wie ich das umgehen kann und wie es richtig berechnet werden kann?
Hier der Code dazu:
Java:
import java.util.Scanner;

public class ProgrammAusführen
{

	public static void main(String[] args)
	{
		//Variablen definieren
		byte programm=0;
		double guthaben = 0;
		double restgeld = 0;
		double betrag = 0;
		final double KAFFEEPREIS1 = 0.75;
		final double KAFFEEPREIS2 = 0.90;
		final double KAFFEEPREIS3 = 1.20;
		
		
		//Programmwahl
		Scanner scan = new Scanner(System.in);
		System.out.println("Bitte wählen sie ihr Programm: ");
		
		programm = scan.nextByte();
		
		System.out.println("Sie haben das Programm " + programm + " gewählt.");
		
		if (programm >= 1 && programm <= 3) {
			//Überprüfung, welches Programm gewählt wurde
			switch(programm)
				{
				//Kaffee 1
				case 1: programm = 1;
					{
						System.out.println("Bitte bezahlen sie: " + KAFFEEPREIS1 + "€");
						guthaben = scan.nextDouble();
						System.out.println("Ihr Guthaben beträgt " + guthaben + "€");
							while(guthaben < KAFFEEPREIS1)
								{
									System.out.println("Bitte werfen sie mehr geld ein." );
									betrag = scan.nextDouble();
									guthaben = guthaben + betrag;
									betrag = 0;
								}
							if (guthaben == KAFFEEPREIS1)
								{
									System.out.println("Vielen Dank, ihr Kaffee wird nun zubereitet." );									
								}
							if (guthaben > KAFFEEPREIS1)
								{
									System.out.println("Vielen Dank, ihr Kaffee wird nun zubereitet.");
									System.out.println("Nach den Zubereitungsvorgang erhalten sie ihr Restgeld.");
									restgeld = guthaben - KAFFEEPREIS1;
									System.out.println("Sie erhalten nun " + restgeld + "€ zurück.");
								}
						break;
					}
				//Kaffee 2
				case 2: programm = 2;
						{
							System.out.println("Bitte bezahlen sie: " + KAFFEEPREIS2 + "€");;
							guthaben = scan.nextDouble();
							System.out.println("Ihr Guthaben beträgt " + guthaben + "€");
							while(guthaben < KAFFEEPREIS2)
								{
									System.out.println("Bitte werfen sie mehr geld ein." );
									betrag = scan.nextDouble();
									guthaben = guthaben + betrag;
									betrag = 0;
								}
							if (guthaben == KAFFEEPREIS2)
								{
									System.out.println("Vielen Dank, ihr Kaffee wird nun zubereitet." );									
								}
							if (guthaben > KAFFEEPREIS2)
								{
									System.out.println("Vielen Dank, ihr Kaffee wird nun zubereitet.");
									System.out.println("Nach den Zubereitungsvorgang erhalten sie ihr Restgeld.");
									restgeld = guthaben - KAFFEEPREIS2;
									System.out.println("Sie erhalten nun " + restgeld + "€ zurück.");
								}
						break;
					}
				//Kaffee 3
				case 3: programm = 3;
						{
							System.out.println("Bitte bezahlen sie: " + KAFFEEPREIS3 + "€");
							guthaben = scan.nextDouble();
							System.out.println("Ihr Guthaben beträgt " + guthaben + "€");
								while(guthaben < KAFFEEPREIS3)
									{
										System.out.println("Bitte werfen sie mehr geld ein." );
										betrag = scan.nextDouble();
										guthaben = guthaben + betrag;
										betrag = 0;
									}
								if (guthaben == KAFFEEPREIS3)
									{
										System.out.println("Vielen Dank, ihr Kaffee wird nun zubereitet." );									
									}
								if (guthaben > KAFFEEPREIS3)
									{
										System.out.println("Vielen Dank, ihr Kaffee wird nun zubereitet.");
										System.out.println("Nach den Zubereitungsvorgang erhalten sie ihr Restgeld.");
										restgeld = guthaben - KAFFEEPREIS3;
										System.out.println("Sie erhalten nun " + restgeld + "€ zurück.");
									}
							break;
						}
			}
		scan.close();
		}
		else
		{
			System.out.println("Leider ist das von Ihnen gewählte Programm nicht vorhanden, bitte wählen sie ein anderes.");
		}
	}

}
Vielen Dank dafür schonmal. 🙂
 
Hallo 🙂

Die Datentypen float und double sind prinzipiell ungenau - das liegt daran, dass man einige Tricks anwenden musste, um reelle Zahlen zu speichern. Denn reelle Zahlen sind noch viel unendlicher, als natürliche Zahlen es schon sind - zwischen 0 und 1 liegen im Bereich der reellen Zahlen mehr Zahlen, es es natürliche Zahlen insgesamt gibt. Da man nicht unendlich viel Speicher hat, muss man eben Abstriche bei der Genauigkeit akzeptieren.

Du könntest die Ausgabe so gestalten, dann wird auf 2 Stellen nach dem Komma gerundet:
Java:
System.out.println(String.format("Sie erhalten nun %.2f € zurück.", restgeld));

String.format ersetzt dabei Platzhalter, die mit % anfangen, durch die danach aufgeführten Parameter. %f steht für Gleitkommazahlen und das .2 bedeutet, dass genau 2 Stellen angezeigt werden sollen, d.h. aus 3 wird dann 3.00 und aus 3.1000001 wird 3.10.

Eine andere Variante, die man in der Praxis anwenden würde, ist die Speicherung sämtlicher Daten in Cent-Beträgen, um auf doubles und floats vollständig verzichten zu können.
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben