# Muenzen zählen



## ocsme (10. Sep 2016)

Hallo,
hab hier ein Programm das ich nicht selbst geschrieben habe und würde gerne wissen wie das funktioniert 

hier mal das Programm:

```
public class muenzen {
        public static void main(String[] args) {
       
        double dollar = Double.parseDouble(args[0]);
        int buck;
        int half;
        int quarter;
        int dime;
        int nickel;
        int penny;

        buck = (int) (dollar/1.00);
        dollar = dollar-buck;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
       
       
       
        half =  (int) (dollar/0.50);
        dollar = dollar-half*0.50;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
        quarter = (int) (dollar/0.25);
        dollar = dollar-quarter*0.25;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
        dime = (int) (dollar/0.10);
        dollar = dollar-dime*0.10;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
        nickel = (int) (dollar/0.05);
        dollar = dollar-nickel*0.05;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
        penny = (int) (dollar/0.01);
       
        System.out.println(buck + " x 1 Dollar");
        System.out.println(half + " x 50 Cent");
        System.out.println(quarter + " x 25 Cent");
        System.out.println(dime + " x 10 Cent");
        System.out.println(nickel + " x 5 Cent");
        System.out.println(penny + " x 1 Cent");
       
        }
}
```

Eigentlich ist es ja ganz einfach es soll eine Eingabe erfolgen über das Terminal und das Programm gibt dann aus wie viele Muenzen die Eingabe ergeben.

Doch leider verstehe ich nicht so ganz wie das gehen soll!!!

```
buck = (int) (dollar/1.00);
        dollar = dollar-buck;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
```

Wenn wir doch den Datentyp double in int umwandeln gehen die Kammerzahlen verloren wieso ist also so etwas möglich? (das es doch geht )
und was soll das ganze hier
dollar = dollar - buck;
dollar = dollar*100 
dollar = math.round(dollar);
dollar = dollar/100

Danke schon mal!
LG


----------



## Meniskusschaden (10. Sep 2016)

Sieh es dir doch mal im Debugger an oder gib vor und nach jedem Rechenschritt die berechnete Variable aus. Dann siehst du ziemlich schnell, was da passiert.

Ein paar Schritte sind wohl eingebaut worden, um Verfälschungen zu korrigieren, die sich aus der begrenzten Genauigkeit von Gleitkommazahlen ergeben. Das wäre in diesem Beispiel wahrscheinlich nicht nötig gewesen, weil ohnehin nur ganze Zahlen ausgegeben werden, so dass das Problem gar nicht in Erscheinung tritt.

Meines Erachtens hätte man deshalb diesen Abschnitt:

```
buck = (int) (dollar/1.00);
        dollar = dollar-buck;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
```
auch so schreiben und die Ungenauigkeit ignorieren können:

```
buck = (int) dollar;
    dollar = dollar-buck;
```
In anderen Fällen kann das aber durchaus relevant sein. Man sollte sich dessen also bewußt sein.


----------



## Xyz1 (10. Sep 2016)

Mach ein paar Ausgaben rein, wenn z. B. `dollar` geändert wird. So verstehst du die Programmablauflogik.


----------



## ocsme (12. Sep 2016)

Ja okay Danke euch beiden  ich hoffe ich kann endlich mal an Java bleiben wollte es schon vor zwei Jahren lernen doch durch Krankheit kam immer etwas dazwischen echt schade!!!

Eine Frage hab ich noch kurz klar könnte ich ja einfach ein paar System.out.print rein hauen aber wie geht das mit dem Debug modus? Gibt es da vielleicht ein Tutorial wo das erklärt wird das würde mich echt interessieren 

LG


----------



## Meniskusschaden (12. Sep 2016)

Dazu gibt es bestimmt jede Menge Tutorials. Man muß aber natürlich eines auswählen, das zur eigenen IDE passt. Ich würde einfach mal bei Google und/oder YouTube danach suchen oder in der Bedienerhilfe der IDE nachsehen.


----------



## VfL_Freak (12. Sep 2016)

ocsme hat gesagt.:


> klar könnte ich ja einfach ein paar System.out.print rein hauen aber wie geht das mit dem Debug modus?


Was genau meinst Du ?? 

Die SysOuts stehen doch im Quellcode .... was hat der Debugmode damit zutun ?
Ist Dir nicht klar, wann was raus kommt und wo ??

Gruß Klaus

EDIT: ach so - Du meinst das Debuggen selbst ??
https://javabeginners.de/IDE/Eclipse_Screenshot-Tutorials/Debugging_mit_Eclipse.php
http://www.vogella.com/tutorials/EclipseDebugging/article.html
https://wiki.byte-welt.net/wiki/Java-Anwendung_remote_debuggen_(mit_Eclipse)


----------



## ocsme (13. Sep 2016)

Hallo,

so also ich hab jetzt überall println rein gehauen und mir die Variablen ausgeben lassen!
Doch wenn ich ganz ehrlich sein darf verstehe ich nur Bahnhof!!!! es fällt mir immer noch mega schwer Algorithmen selbst zu entwickeln und diese zu verstehen! Wie lernt man das am besten?

Des weiteren verstehe ich nicht ganz wenn ich doch eine Variable von Double umwandele zu int geht die Gleitkommazahl doch verloren wieso also bekomme ich sie oben im Programm raus? oh man man man...!!!!

LG


----------



## VfL_Freak (13. Sep 2016)

Und was geben die SysOuts aus? 



ocsme hat gesagt.:


> Des weiteren verstehe ich nicht ganz wenn ich doch eine Variable von Double umwandele zu int geht die Gleitkommazahl doch verloren wieso also bekomme ich sie oben im Programm raus?


WO bekommst Du eine Nachkommazahl raus ??? 
Wenn den Code mit "dollar = 7.25" aufrufe, bekomme ich dies IMHO korrekte Ergebnis:
7 x 1 Dollar
0 x 50 Cent
1 x 25 Cent
0 x 10 Cent
0 x 5 Cent
0 x 1 Cent

Gruß Klaus


----------



## ocsme (13. Sep 2016)

Klaus na das meine ich doch wenn ich double = 7.25 eingebe und die Variable umwandele in ein INT dann schneidet er mir doch die 0.25 ab! Oder irgendwie doch nicht wie man an dem Programm oben erkennen kann! und wieso macht er das nicht das ist mir derzeit irgendwie zu hoch =( 

wenn nicht lass ich mal unsere Übungen weg und lese mich mehr in den stoff ein und mache andere Übungsaufgaben das war eine aufgabe aus unserer Java Vorlesung  eine von den leichtesten  und noch nicht mal das bekomme ich hine "Kopf schütteln!"


----------



## flopalko (13. Sep 2016)

Ja das stimmt schon, er schneidet die 0.25 ab. Aber schau mal in die nächste Zeile was da passiert.
Wie gesagt mach nach jeder Zeile ein sysout der aktuellen Variable, dann siehst du was passiert.


----------



## VfL_Freak (13. Sep 2016)

ocsme hat gesagt.:


> Oder irgendwie doch nicht wie man an dem Programm oben erkennen kann!


Hä?? 
WAS glaubst Du denn am Programm zu erkennen?? 

Durch das Casten bei *buck = (int)(dollar/1.00)* wird das Ergebnis der Divison zu einem Integer!
Da Du nur die gecasteten Ergebnisse ausgibst, kommt das raus, was ich oben schrieb !!

Was hättest Du denn als Ausgabe erwartet ?? 

gruß Klaus


----------



## flopalko (13. Sep 2016)

Ich denke er meint er hat dann die 0.25 für immer verloren und kann daher nicht die restlichen Münzen berechnen. Darauf dass dem nicht so ist habe ich oben schon hingewiesen


----------



## VfL_Freak (13. Sep 2016)

flopalko hat gesagt.:


> Ich denke er meint er hat dann die 0.25 für immer verloren


Ah, ok, so langsam verstehe ich ....

Aber da die Variable *dollar* ja nicht verändert wird, wird in den folgenden Zeilen weiter lustig mit 7.25 gerechnet !!!

Gruß Klaus


----------



## flopalko (13. Sep 2016)

Richtig und dann wird dollar-buck berechnet (also 7.25-7 = 0.25). Damit wird dann weiter gerechnet. Jetzt hast du aber schon genug Hinweise. Wenn du es jetzt noch immer nicht verstehst, dann mach dir nach jeder Zeile eine Ausgabe, dann kann man es nicht nicht verstehen.


----------



## ocsme (13. Sep 2016)

achherje so doof  
Danke Leute jetzt hab ich es verstanden ich dachte wenn ich die Variable in ein INT wandele  das Java dann hin geht und mir die Gleitkommazahl eben abschneidet und verwirft  
oh man 
aber danke für eure Hilfe ihr seit die Besten 
werde mal schauen das ich solche Sachen eben alleine hin bekomme und wenn ich fragen habe weis ich ja wo ich Hilfe bekommen kann 

LG


----------



## flopalko (13. Sep 2016)

Nein du hast es anscheinend noch immer nicht verstanden:


ocsme hat gesagt.:


> Danke Leute jetzt hab ich es verstanden ich dachte wenn ich die Variable in ein INT wandele  das Java dann hin geht und mir die Gleitkommazahl eben abschneidet und verwirft


Es ist auch so, dass wenn du eine Gleitkommazahl in eine Integervariable umwandelst die Kommastellen verloren gehen. Aber in diesem Programm wird die umgewandelte Gleitkommazahl einer neuen Variable zugewiesen, dadurch bleibt bei der ursprünglichen Variable alles beim Alten.
LG


----------



## ocsme (13. Sep 2016)

Nööö... dann verstehe ich es einfach immer noch nicht
und ich weis ehrlich gesagt auch nicht mal wann und wo ich die System.outs setzen muss!
naja trotzdem danke!
lg

so hab mal die System.outs so gesetzt:

```
public class muenzen {
        public static void main(String[] args) {
    
        double dollar = Double.parseDouble(args[0]);
        int buck;
        int half;
        int quarter;
        int dime;
        int nickel;
        int penny;

        buck = (int) (dollar/1.00);
        System.out.println(buck);
        dollar = dollar-buck;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
    
    
        half =  (int) (dollar/0.50);
        System.out.println(half);
        dollar = dollar-half*0.50;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
    
        quarter = (int) (dollar/0.25);
        System.out.println(quarter);
        dollar = dollar-quarter*0.25;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
    
        dime = (int) (dollar/0.10);
        System.out.println(dime);
        dollar = dollar-dime*0.10;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
    
        nickel = (int) (dollar/0.05);
        System.out.println(nickel);
        dollar = dollar-nickel*0.05;
        dollar = dollar*100;
        dollar = Math.round(dollar);
        dollar = dollar/100;
        penny = (int) (dollar/0.01);
        System.out.println(penny);
    
        System.out.println(buck + " x 1 Dollar");
        System.out.println(half + " x 50 Cent");
        System.out.println(quarter + " x 25 Cent");
        System.out.println(dime + " x 10 Cent");
        System.out.println(nickel + " x 5 Cent");
        System.out.println(penny + " x 1 Cent");
    
        }
}
```

dabei kommt das hier raus:
12
0
0
2
0
1
12 x 1 Dollar
0 x 50 Cent
0 x 25 Cent
2 x 10 Cent
0 x 5 Cent
1 x 1 Cent

würde dann nicht diese Anweisung reichen?

```
half =  (int) (dollar/0.50);
```
hehe NEIN das geht nicht
12 x 1 Dollar
24 x 50 Cent
48 x 25 Cent
122 x 10 Cent
244 x 5 Cent
1221 x 1 Cent


___
wenn nicht kann das Thema hier jetzt geschlossen werden ich hab es nicht verstanden und werde es auch nie!!!
lg


----------



## flopalko (13. Sep 2016)

ocsme hat gesagt.:


> ich hab es nicht verstanden und werde es auch nie!!!


Doch das bekommen wir schon noch hin  So dann versuche ich dir den Code Schritt für Schritt zu erläutern:
Deine Variable mit der du die ganzen Berechnungen anstellst ist dollar. Daher wäre es sinnvoller dir in den sysouts dollar anzeigen zu lassen. Mach das mal und wenn das nicht hilft lies weiter.

Wie bereits erwähnt ist deine Variable wo dein Gesamtbetrag drinnen ist dollar. Als erstes willst du einmal wissen wie viele 1$ (buck) du zurückgeben musst. Daher schneidest du den Kommateil deines Betrags ab und rechnest das dividiert durch 1. Nehmen wir an dein Betrag war 7.86$. Da kommt logischerweise 7 raus.
Nun ziehst du von den 7.86$ 7*1$ ab. 0.86$ bleiben über.

```
dollar = dollar*100;
dollar = Math.round(dollar);
dollar = dollar/100;
```
Diese 3 Zeilen sind für folgendes da. Nicht jede nicht periodische Zahl des Dezimalsystems ist im Binärsystem nicht periodisch darstellbar. (0.1 dezimal ist z.B. im Binärsystem eine periodische Zahl, 1/3 dezimal ist hingegen im Binärsystem nicht periodisch) Nimm dies einfach mal hin, wenn du es nicht verstehst, du solltest dir aber noch anschauen warum dies so ist. Damit eben solche Ungenauigkeiten ausgemerzt werden multiplizierst du mal 100 (im Beispiel hast du dann also 86.0) rundest auf den nähesten Integer und dividierst wieder durch 100. (wenn du zum Beispiel 0.8599999999999 hast hast du nach den 3 Zeilen wieder 0.86)
Nun berechnest du die Anzahl der 50cent Stücke. Dafür dividierst du deine Rechenvariable dollar (die jetzt den Wert 0.86 hat) durch 0.5 und schneidest wieder den Nachkommateil ab. In deinem Beispiel kommt hier 1 raus. Folgend ziehst du von deiner Rechenvariable dollar (0.86) die Wertigkeit der Münze mal der Anzahl wie oft du sie herausgibst ab. In deinem Beispiel also 0.86-1*0.5. Das Ergebnis (0.36) speicherst du wieder in deiner Rechenvariable dollar.
Genau das gleiche passiert dann noch für die Wertigkeiten der Münzen quarter, dime, nickel und penny.

Jetzt solltest du den Algorithmus verstehen, wenn nicht lass dir wie gesagt nach jedem Schritt die Variable dollar ausgeben, dann solltest du es verstehen. Falls du dies noch immer nicht tust, sag nochmal wo genau es noch hapert, dann kann man versuchen es dir nochmal zu erklären.
LG


----------



## ocsme (13. Sep 2016)

oh mein gott =) ihr gebt euch ja mega Mühe =) ich bin immer zu schnell frustriert hatte gleich den PC wieder ausgemacht und liege im Bett  doch schlaffen kann ich nicht da ich mir die ganze Zeit um dieses Problem Gedanken mache 
Danke für die tolle Erklärung ich werde es mir morgen früh gleich genauer anschauen dann werde ich mir ab sofort mehr mühe geben denn ich will es schaffen  Java Programmieren können und danach noch weitere sprachen erlernen  

Vielen Lieben Dank ihr seit wirklich die besten 
Liebe Grüße


----------

