Hallo,
Ich habe da ein kleines Problem.
Zur Lage:
Ich implementiere gerade die Bruchrechnung, die ich für einen Optimierungsalgorithmus benötige.
Probleme habe ich mit dem Kürzen von Brüchen bei der Addition. Siehe Quelltextausschnitte unten:
Die Addition gibt soweit korrekte Brüche aus, solange ein Bruch nicht mit einem double-Wert erzeugt wird, der neun oder mehr Nachkommastellen hat. An diesem Falle wird ein Bruch 0/0 erzeugt. Diesen Fehler kann ich mir nicht erklären und bitte daher um Eure fachkundliche Hilfe.
Hinweis: Ich weiß, ich kann den Doublewert natürlich kürzen. Dennoch interessiert mich, warum dieses Problem auftritt.
Kann Java entsprechend lange doubles nicht mehr verarbeiten oder liegt da möglicherweise ein ärgerlicher Fehler in meiner Implementierung vor?
Liebe Grüße
Getätige Eingaben (teilweise inkorrekter Code. Nur zur Verdeutlichung. Ein Aufruf von Bruch.add war in der externen Testklasse nicht möglich)
Zunächst einmal die Konstruktoren (ja, ich weiß, ich habe mich nicht an unbedingt an die Namenskonventionen gehalten). JavaDoc zur Übersichtlichkeit weggelassen und durch kleine Kommentare ersetzt
Als nächstes die beiden Hilfsmethoden des letzten Konstruktors.
So, nun noch die ebenfalls genutzten Methoden kuerzen(), erweitern() und die obere Additionsfunktion (es gibt weitere, überladene Methoden. Diese wurden jedoch hier nicht verwendet)
Ich habe da ein kleines Problem.
Zur Lage:
Ich implementiere gerade die Bruchrechnung, die ich für einen Optimierungsalgorithmus benötige.
Probleme habe ich mit dem Kürzen von Brüchen bei der Addition. Siehe Quelltextausschnitte unten:
Die Addition gibt soweit korrekte Brüche aus, solange ein Bruch nicht mit einem double-Wert erzeugt wird, der neun oder mehr Nachkommastellen hat. An diesem Falle wird ein Bruch 0/0 erzeugt. Diesen Fehler kann ich mir nicht erklären und bitte daher um Eure fachkundliche Hilfe.
Hinweis: Ich weiß, ich kann den Doublewert natürlich kürzen. Dennoch interessiert mich, warum dieses Problem auftritt.
Kann Java entsprechend lange doubles nicht mehr verarbeiten oder liegt da möglicherweise ein ärgerlicher Fehler in meiner Implementierung vor?
Liebe Grüße
Getätige Eingaben (teilweise inkorrekter Code. Nur zur Verdeutlichung. Ein Aufruf von Bruch.add war in der externen Testklasse nicht möglich)
Code:
Bruch param1 = new Bruch(2,4);
Bruch param2 = new Bruch(1,3);
Bruch param3 = new Bruch(1.333);
Bruch param4 = new Bruch(1.333333333);
Bruch.add(param1, param2); //korrektes Ergebnis wird korrekt gekürzt ausgegeben;
Bruch.add(param1, param3); //korrektes Ergebnis wird korrekt gekürzt ausgegeben
Bruch.add(param1, param4); //ausgegebenes Ergebnis: 0/0
Zunächst einmal die Konstruktoren (ja, ich weiß, ich habe mich nicht an unbedingt an die Namenskonventionen gehalten). JavaDoc zur Übersichtlichkeit weggelassen und durch kleine Kommentare ersetzt
Code:
//Hauptkonstruktor. Damit Änderung nicht mehrfach benötigt
public Bruch(int zaehler, int nenner){
if(nenner == 0){
throw new IllegalArgumentException();
}
this.zaehler = zaehler;
this.nenner = nenner;
kuerzen();
}
//****************************************************************
public Bruch(int zahl){
this(zahl, 1);
}
//****************************************************************
public Bruch(double zahl){
this(createNumer(zahl), createDenom(zahl));
}
Als nächstes die beiden Hilfsmethoden des letzten Konstruktors.
Code:
private static int createNumer(double zahl){
String sTemp = Double.toString(zahl);
String sTempB = "";
String sTempA = "";
boolean bTemp = false;
for(int i=0;i<sTemp.length();i++){
if(sTemp.substring(i, i+1).equals(("."))){
bTemp = true;
continue;
}
if(bTemp){
sTempA = sTempA.concat(sTemp.substring(i, i+1));
}else{
sTempB = sTempB.concat(sTemp.substring(i, i+1));
}
}
sTemp = sTempB + sTempA;
return Integer.parseInt(sTemp);
}
//*********************************************************
private static int createDenom(double zahl){
int iTemp = 0;
String sTemp = Double.toString(zahl);
boolean bTemp = false;
for(int i=0; i<sTemp.length();i++){
if(sTemp.substring(i, i+1).equals(".")){
bTemp = true;
continue;
}
if(bTemp){
iTemp++;
}
}
return (int) Math.pow(10, iTemp);
}
So, nun noch die ebenfalls genutzten Methoden kuerzen(), erweitern() und die obere Additionsfunktion (es gibt weitere, überladene Methoden. Diese wurden jedoch hier nicht verwendet)
Code:
public void kuerzen(){
if(this.zaehler!=0){
int ggt = ggt(this.zaehler, this.nenner);
this.zaehler = this.zaehler / ggt;
this.nenner = this.nenner / ggt;
}else{
System.out.println("WARNING (1): [bruch.kuerzen()]: numerator == 0");
System.out.println("WARNING (2): [bruch.kuerzen()]: fraction will not be reduced");
}
}
//***************************************************************
public void erweitern(int num){
if(num == 0){
throw new IllegalArgumentException();
}
this.zaehler = this.zaehler*num;
this.nenner = this.nenner*num;
}
//***************************************************************
public Bruch add(Bruch a, Bruch b){
Bruch c = new Bruch(a.zaehler,a.nenner);
Bruch d = new Bruch(b.zaehler,b.nenner);
c.erweitern(b.nenner);
d.erweitern(a.nenner);
return(new Bruch(c.zaehler+d.zaehler,c.nenner));
}
Zuletzt bearbeitet: