Was habe ich hier falsch programmiert (Java; BlueJ)?
Hi Leute!
Ich habe folgendes Problem: Wir sollen in BlueJ einen Bruchrechner programmieren, der mit normalen Brüchen, gemischten Zahlen und Dezimalzahlen rechnen kann.
Bei den Dezimalzahlen habe ich nur das Problem, dass die Dezimalzahl nicht angezeigt wird bzw. immer auf 0,0 steht. Hier dazu mal der Code:
public class Dezimalzahl extends GemischterBruch
{
private double dezimalZahl;
public Dezimalzahl(int pZaehler, int pNenner)
{
//hier wird der Zähler und Nenner Zugewiesen
super(pZaehler,pNenner);
//hier wollte ich die Dezimalzahl ausrechnen
dezimalZahl = super.getZaehler()/super.getNenner();
}
}
Weiß jemand, wie ich die Programmierung verbessern kann, sodass alles klappt?
Wäre froh über schnelle und hilfreiche Antworten!
LG, Oldcoockie :)
2 Antworten
Dein konkretes "Problem" warum 0.0 raus kommt, liegt daran:
du hast als Eingangsparameter zwei Integer werte, also zwei Ganzzahlen. - Mit diesen beiden Werten führst du die Division durch, und erst danach werden diese einem double Wert zugewiesen.
D.h. aus dem hier:
dezimalZahl = super.getZaehler() / super.getNenner();
Müsste folgendes werden:
dezimalzahl = (double) super.getZaehler() / (double) super.getNenner();
sprich: sowohl Zähler als auch Nenner müssen vor der Division in double konvertiert umgewandelt werden.
Sofern du aber mit Java wirklich rechnen möchtest, rate ich davon ab, auf diese weise zu machen, sondern würde auf BigDecimal zurück zu greifen, da Rechenoperationen auf Binärer-Ebene statt finden, und es aufgrund dessen manchmal zu 'falschen' Ergebnissen kommt.
(Siehe hier: http://stackoverflow.com/questions/16707397/whats-wrong-with-this-simple-double-calculation )
dezimalzahl = BigDecimal.valueOf(super.getZaehler()).divide(BigDecimal.valueOf(super.getNenner()), MathContext.DECIMAL64).doubleValue();
Ein allgemeiner Verbesserungsvorschlag wäre jedoch noch: Dass du eine Exception wirfst, sofern der Nenner 0 ist um Division durch 0 zu verhindern.
poste mal dein Code(abschnitt) hier oder auf pastebin oder so, dann können wir die bestimmt weiterhelfen. denn die von uns genannten Methoden Funktionieren eigentlich...
alles klar, ich füge dann aber nur die Attribute und den Kostuktor ein, sonst wäre es zu viel.
hier die Klasse "Bruch":
public class Bruch
{
private int zaehler;
private int nenner;
private int zwischenErgebnisZaehler;
public Bruch(int pZaehler, int pNenner)
{
zaehler=pZaehler;
nenner=pNenner;
}}
Die Klasse "GeteilterBruch":
public class GemischterBruch extends Bruch
{
private int ganzeZahl;
private Bruch bruchAnteil;
public GemischterBruch(int pZaehler, int pNenner)
{
super(pZaehler,pNenner);
gemischteZahl();
}}
und die Klasse "Dezimalzahl":
private int dezimalZahl;
public Dezimalzahl(int pZaehler, int pNenner)
{
super(pZaehler,pNenner);
dezimalZahl = (double) super.getZaehler() / (double) super.getNenner();
}
In deiner Klasse: Dezimalzahl muss der dein Attribut: dezimalZahl als double deklariert werden, das ist der Fehler.
Danke für die Antwort, ich habe soweit alles verstanden. Nur sagt mir BlueJ jetzt
"incompatible types: possible lossy conversion from double to int" bei
dezimalZahl = (double) super.getZaehler()/(double)super.getNenner(); //dieser Zeile
Was ist da dann falsch?
Habe auch die anderen Vorschläge von SirNik ausprobiert, kommt der gleiche Fehler.
(Entschuldigung für mein mangelndes wissen, bin noch ein Einsteiger (; )
LG, Oldcoockie :)
Hallo :D
Dein Zähler und dein Nenner sind jeweils eine Ganzzahl, ein int, das soweit in Ordnung.
Das Problem allerdings liegt darin, dass wenn du eine Ganzzahl durch eine Ganzzahl teilst, auch eine Ganzzahl rauskommt. Die Komma stellen werden einfach weggestrichen.
Bsp:
1/2 = 0,5, jedoch kommt dort 0 heraus
6/5 = 1,2, heraus kommt aber 1
Um das Problem zu lösen musst du casten, also eine Typunwandlung durchführen:
dezimalZahl = (double) (zaehler/nenner);
Oder
dezimalZahl = zaehler / (nenner × 1.0);
...
Es gibt mehrere Möglichkeiten zu casten.
Im ersten Bsp castest du die Rechnung mit (double).
Im zweiten Bsp rechnest du den nenner ODER den zaehler oder beides erst mal 1.0, das hat den Effekt, dass dein nenner in ein Double gecastet wird und da du nun auch durch ein Double teilst und nicht mehr durch ein int, kommt das richtige Ergebnis raus
:) Hoffe konnte dir helfen
Danke für die Antwort, hat mir sehr geholfen! LG, Oldcoockie :)
dezimalZahl = (double) (zaehler/nenner);
Dieser Cast ist unnötig. denn das passiert ja bereits auch ohne dass man es explizit benennen muss.
In diesem Falle ist der Wert jedoch immer noch falsch, denn die Division findet hier immer noch mit Ganzzahlen statt.
Du hast natürlich recht, sry, mein Fehler: Es müsste dann so aussehen:
dezimalZahl = (double) zaehler / (double) nenner;
oder eben mit der Multiplikation einer der beiden Zahlen mit 1.0
Oh, hab ich garnicht bemerkt! Muss ich nächstes mal wirklich aufmerksamer sein. Vielen Dank für eure Hilfe! LG, Oldcoockie :)