# Zahlen-Aufgabe



## minka000 (11. Jan 2010)

Hallo!

Ich habe folgende Aufgabe gestellt bekommen:

Gegeben sei die abstrakte Klasse


```
abstract class Zahl implements Comparable {
abstract public Zahl add(Zahl z);
abstract public Zahl sub(Zahl z);
abstract public Zahl mul(Zahl z);
abstract public Zahl div(Zahl z);
abstract public int compareTo(Object k);
public static void sort(Zahl[] k) {
...
}
}
```

Vervollständigen Sie die Methode sort(Zahl[] k), sodass das Parameter-Feld aufsteigend
sortiert wird.
Schreiben Sie konkrete Klassen Nat, Ganz und Rat, die die abstrakte Klasse Zahl
erweitern und natürliche, ganze bzw. rationale Zahlen repräsentieren. Stellen Sie dabei
eine natürliche Zahl durch einen nichtnegativen long-Wert, eine ganze Zahl durch einen
long-Wert und eine rationale Zahl durch einen long-Wert (Zähler) und einen positiven long-
Wert (Nenner) dar. Achten Sie darauf, dass die Darstellung rationaler Zahlen eindeutig
und gekürzt ist. Fügen Sie geeignete Konstruktoren und die toString-Methode hinzu.
Gegeben seien die fünf rationalen Zahlen

-3/7 , 1/3 , 5/6 , 2/9 und 1/17.

Berechnen Sie schriftlich
den Wert des Ausdrucks

[(-3/7) - (1/3)] / [(5/6) + (2/9) * (1/17)]


und überprüfen Sie Ihr Ergebnis mit dem folgenden Programmfragment:


```
Zahl[] r = new Rat[5];
r[0] = new Rat(-3,7);
r[1] = new Rat(1,3);
r[2] = new Rat(5,6);
r[3] = new Rat(2,9);
r[4] = new Rat(1,17);
Zahl e = (r[0].sub(r[1])).div(r[2].add(r[3].mul(r[4])));
System.out.println(e);
```


Sortieren Sie dann das Feld r mit der Methode sort und geben Sie das sortierte Feld aus.
Berechnen Sie anschließend mit Ihrem Programm den genauen Wert der Summe

Summe(i=1 bis 20) (1/i) = (1/1)+(1/2)+...+(1/20)


Geben Sie das Ergebnis auch als double-Wert aus.
Führen Sie weitere Tests – auch mit natürlichen und ganzen Zahlen – durch und zeigen
Sie die Testergebnisse Ihrem Tutor.
Beim Auftreten eines fehlerhaften Werts (z. B. einer negativen natürlichen Zahl) soll
das Programm mit einer entsprechenden Meldung beendet werden (System.exit(1)).



Entschuldigt, dass die Brüche und die Summe so dargestellt sind, aber leider konnte ich hier mit Latex nichts schreiben 

So ich hab jetzt mal angefangen die konkreten Klassen Nat, Ganz u. Rat zu schreiben:


```
public class Nat extends Zahl {
	
	long n;
	
	public Nat (long n) {
		if ( nat < 0) {
			System.out.println("Keine natürliche Zahl!");
			System.exit(1)
		}
		this.n = n;	
	}
	
	public String toString() {
		return Nat = n
	}
}
```


```
public class Ganz extends Zahl {
	
	long g;
	
	public Zahl(long g) {
		this.g = g;
	}
	
	public String toString() {
		return Ganz = g;
	}	
}
```


```
public class Rat extends Zahl {
	
	long zaehler, nenner;
	
	public Rat(long zaehler, long nenner) {
		if (nenner < 0) {
			System.out.println("Der Nenner darf nicht negativ sein");
			System.exit(1);
		}
		this.zaehler = zaehler;
		this.nenner = nenner;
	}
	
	public String toString() {
		return Rat = zaehler/nenner;
	}	
}
```


Ich weiss das ich noch nicht sonderlich weit gekommen bin. Aber ich wollte erstmal von euch wissen ob das bisher denn schonmal richtig ist? Bzw. gehört in diese Klassen noch mehr hinein?

Über Antworten würde ich mich sehr freuen 

mfg minka000


----------



## Marco13 (11. Jan 2010)

Beim ersten Drüberschauen: Da fehlen ja noch die ganzen Methoden add, mul usw... bisher müßten die Klassen ja selbst noch "abstract" sein, weil sie diese (abstrakten) Methoden nicht implementieren....

Ein negativer Nenner ist übrigens weit weniger schlimm, als "0" als Nenner


----------



## JavaN00by (14. Jan 2010)

ich hoffe ihr könnt bei der aufgabe helfen, damit wäre auch mir sehr geholfen!


----------



## SlaterB (14. Jan 2010)

auf eine einzelne Zeile, die begrenzt als 'Frage' zu bezeichnen ist, ohne Code oder sonstige eigene Anstrengungen, wird nicht viel kommen

soviel wie von minka000 ist andererseits auch nicht gut, das liest doch keiner durch


----------



## heoyeah (14. Jan 2010)

Hallo,
ich muss die Aufgabe auch machen, aber irgendwie funktioniert die klasse für rationalen Zahlen nicht.
Könnte mir jemand sagen woran das liegt?


```
public class Rat extends Zahl {
    
    private long zaehler;
    private long nenner;
    
  
    public Rat(long zaehler, long nenner) {
      
      this.zaehler = zaehler;
      
      if (zaehler == 0) {
       
        nenner = 0;
      
      }

      if (nenner < 0) {
    	
        zaehler *= -1;
        this.nenner = -nenner;
      
      }
      else {
       
        this.nenner = nenner;
      
      }
      kuerzen();
   }
    
    private long getGgt(long a, long b) {
      
      while ( a > 0 &&  b > 0) {
      
        if ( a > b ) {
          
          a = a % b;
        
        } 
        else {
        
           b = b % a;
        
        }  
      } 
      return Math.max(a, b);
    }

    private void kuerzen() {
       
      long ggt = getGgt(Math.abs(zaehler), nenner);
      if (ggt > 0) {
        
    	zaehler = zaehler / ggt;
        nenner = nenner / ggt;   
      }         
    }

    public long getZaehler() {

        return zaehler;

      }
    
    public long getNenner() {

       return nenner;

    }
    
    public void setZahl(long zaehler,long nenner){
        
        this.zaehler = zaehler;
        this.nenner = nenner;
       
    } 
    
    public String toString() {
   
       return zaehler + "/" + nenner;
     
    }
   
    public Rat add(Zahl r)  {
    
       return new Rat(this.zaehler * r.nenner + this.nenner * r.zaehler, this.nenner * r.nenner);
    
    }
   
    public Rat sub(Zahl r) {
     
       return new Rat(this.zaehler * r.nenner - this.zaehler * r.nenner,this.nenner * r.nenner);
    
    } 
    
    public Rat mul(Zahl r) {
       
       return new Rat(this.zaehler * r.zaehler, this.nenner * nenner);
    
    }

    public Rat div(Zahl r) {
     
        return new Rat(this.zaehler * r.nenner,this.nenner * r.zaehler);
    
    }

	@Override
	public int compareTo(Object o) {
		// TODO Auto-generated method stub
		return 0;
	}

}
```


----------



## SlaterB (14. Jan 2010)

was genau funktioniert daran nicht, idealerweise mit main-Methode,
welche Eingaben, welche Ausgaben, was soll stattdessen passieren


----------



## heoyeah (14. Jan 2010)

Ich habe die Klasse so getestet.

```
public class Test {
  
  public static void main(final String[] args) {
    Zahl[] r = new Rat[5];
    r[0] = new Rat(-3,7);
    r[1] = new Rat(1,3);
    r[2] = new Rat(5,6);
    r[3] = new Rat(2,9);
    r[4] = new Rat(1,17);
    System.out.println(r[0]);
    System.out.println(r[0].sub(r[1]));
    Zahl e = (r[0].sub(r[1])).div(r[2].add(r[3].mul(r[4])));
    System.out.println(e);
  }
}
```
und es kommt folgende Fehlermeldung

```
-3/7
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The type Rat must implement the inherited abstract method Zahl.sub(Zahl)

	at Rat.sub(Rat.java:1)
	at Test.main(Test.java:12)
```


----------



## SlaterB (14. Jan 2010)

oh, ganz vergessen,
also:
die Fehlermeldung ist etwas ungünstig, sie versteckt ihre wahre Ursache, 
wenn du die wirklich nirgendwo siehst, dann empfehle ich dir dringend eine Entwicklungsumgebung wie Eclipse,

dort wird man sofort darauf hingewiesen, dass in der eigentlich richtig überschreibenden Methode sub(Zahl) in Rad ein Fehler vorliegt,
und zwar ist bei
> return new Rat(this.zaehler * r.nenner
der Zugriff auf r.nenner nicht erlaubt, denn r ist ja nur eine Zahl, nicht unbedingt ein Rat,

du könntest das Zahl-Objekt auf Rat casten, wenn du glaubst, dass es ein Rat ist, 
wie du mit einer beliebigen Zahl richtig weiterrechnest kann ich gar nicht beantworten,
bietet Zahl nicht noch mehr Methoden?


----------



## Leuchtturm (15. Jan 2010)

Ich muss die Aufgabe auch machen und hab schon mit den natürlichen Zahlen probleme.
Hab jetzt folgendes gemacht:


```
abstract class Nat extends Zahl {
    
   private long n;


    public Nat() {
        n = 0;
    }
    
    public Nat(long n){
        if (n < 0) {
            System.out.println("Fehler! Keine natürliche Zahl!");
            System.exit(1);
         }
         else 
            this.n = n;   
   }

    
    public long add(Nat r) {
       return this.n += r.n;
   }   

   public long sub(Nat r) {
    return this.n -= r.n;
   }
   
   public long mul(Nat r) {
     return this.n *= r.n;    
   }
    
    public long div(Nat r) {
       return this.n /= r.n; 
    }

}
```

oder is das doch ganz okay??  ich glaub mit den Bezeichnern bin ich durcheinander gekommen, glaub nicht das das so richtig ist. und ist das richtig das die klasse abstract is??


schonmal vielen DanK!!!!! :rtfm:


----------



## SlaterB (15. Jan 2010)

add(Nat r)
überschreibt nicht die Methode add(Zahl)
korrekterweise ist auch diese Klasse bei dir abstract


----------



## Marco13 (15. Jan 2010)

Was heißt "korrekterweise" - so war das sicher nicht gemeint. Die Methode
abstract public Zahl add(Zahl z);
soll ein neues Zahl-Object liefern - und keinen long-Wert.

Abgesehen davon würde mir spontan auch keine Lösung für diese Aufgabe einfallen, die nicht irgendwie Bauchschmerzen verursachen würde: Im Moment müßte man in JEDER implementierung JEDER Operation mit instanceof prüfen, was denn das übergebene Objekt für eine "Zahl" ist. 

Am (im OO-Sinne) "schönsten" wäre eigentlich
[c]class Nat extends Rat[/c] und
[c]class Ganz extends Rat[/c]
(müßte man nochmal über Lishkov nachdenken, aber mathematisch gesehen wäre das ja nicht ganz unsinning...)

Bei anderen Zahlenarten würde es ihn dann zwar auch raushauen, aber ... so gesehen müßte es eine abstrakte Basisklasse "Real" (oder was NOCH allgemeineres) geben, und alles in einem BigDecimal gespeichert werden :autsch:

EDIT: Wobei diese "oberste" Klasse, die in einem BigDecimal speichert, in diesem Fall ja "Zahl" sein könnte


----------



## Leuchtturm (16. Jan 2010)

Marco13 hat gesagt.:


> Was heißt "korrekterweise" - so war das sicher nicht gemeint. Die Methode
> abstract public Zahl add(Zahl z);
> soll ein neues Zahl-Object liefern - und keinen long-Wert.



Ja richtig! vllt mit toString MEthode?


----------



## Leuchtturm (16. Jan 2010)

Ich hab jetzt mal ne Lösung fürs addieren von nem Kommilitonen ders eigentlich drauf hat. 



```
public Nat add(Zahl z) {
   Nat ausgabe = new Nat();
   if(z instanceof Nat) {
      Nat summand = (Nat) z;
      ausgabe = new Nat(this.wert_nat + summand.wert_nat);
   }
   else {
     System.out.println("Es können nur natürliche Zahlen zu natürlichen Zahlen addiert werden!");
     System.exit(1);
  }
  return ausgabe;
}
```


Was sagt ihr dazu=? ???:L


----------



## Landei (16. Jan 2010)

Leuchtturm hat gesagt.:


> Ich hab jetzt mal ne Lösung fürs addieren von nem Kommilitonen ders eigentlich drauf hat.
> 
> 
> 
> ...



Das ist schon nicht schlecht. Es ist natürlich dumm, dass das Argument wegen des vorgegebenen Interfaces Zahl sein muss (man bräuchte Generics, um das "richtig" zu machen). Ich würde es so schreiben:


```
public Nat add(Zahl z) {
   if(z instanceof Nat) {
      Nat summand = (Nat) z;
      return new Nat(this.wert_nat + summand.wert_nat);
   } else {
     throw new IllegalArgumentException("Es können nur natürliche Zahlen zu natürlichen Zahlen addiert werden!");
  }
}
```
Der Vorteil der Exception ist, dass die aufrufende Methode auf das Problem reagieren kann, wenn sie will, und nicht gleich das ganze Programm abgeschossen wird.


----------



## addu (16. Jan 2010)

habe diese Lösung fürs addieren:

```
public Zahl add(Zahl z) {
		if (z instanceof Nat) {
			Nat n = (Nat) z;
			this.n += n.n;
			return new Nat(this.n);
		} 
		else
			System.exit(1);
			return new Nat();
```
analog dazu habe ich die methoden sub, mul und div geschrieben, funktioneirt bisher ganz gut, allerdings komme ich bei den rationalen zahlen nicht weiter:

```
public class Rat extends Zahl {

	private long zaehler, nenner;
	
	public Rat() {
		zaehler = 0;
		nenner = 0;
	}
	public Rat(long zaehler) {
		this.zaehler = zaehler;
	}
	public Rat(long zaehler, long nenner) {
		this.nenner = nenner;
	}

	public String toString() {
		return Long.toString(this.zaehler)+ "/" + Long.toString(this.nenner);
	}

	public int compareTo(Object k) {
		if (k instanceof Rat) {
			Rat zaehler = (Rat) k;
			Rat nenner = (Rat) k;
			if (this.zaehler < zaehler.zaehler && this.nenner >= nenner.nenner) {
				return -1;
			} 
			else if (this.zaehler > zaehler.zaehler && this.nenner <= nenner.nenner) {
				return 1;
			} 
			else
				return 0;
		} 
		else
			System.exit(1);
			return 1337;
	}

	public Zahl add(Zahl z) {
		if(z instanceof Rat) {
			Rat zaehler = (Rat) z;
			Rat nenner = (Rat) z;
			this.zaehler = (this.zaehler * nenner.nenner) + (zaehler.zaehler * this.nenner);
			this.nenner *= nenner.nenner;
			return new Rat(this.zaehler, this.nenner);
		}
		else
			System.exit(1);
			return new Rat();
	}

	public Zahl sub(Zahl z) {
		if(z instanceof Rat) {
			Rat zaehler = (Rat) z;
			Rat nenner = (Rat) z;
			this.zaehler = (this.zaehler * nenner.nenner) - (zaehler.zaehler * this.nenner);
			this.nenner *= nenner.nenner;
			return new Rat(this.zaehler, this.nenner);
		}
		else
			System.exit(1);
			return new Rat();
	}

	public Zahl mul(Zahl z) {
		
		if(z instanceof Rat) {
			Rat zaehler = (Rat) z;
			Rat nenner = (Rat) z;
			this.zaehler *= zaehler.zaehler;
			this.nenner *= nenner.nenner;
			return new Rat(this.zaehler, this.nenner);
		
		}
		else
			System.exit(1);
			return new Rat();
	}

	public Zahl div(Zahl z) {
		if(z instanceof Rat) {
			Rat zaehler = (Rat) z;
			Rat nenner = (Rat) z;
			this.zaehler *= nenner.nenner;
			this.nenner *= zaehler.zaehler;
			return new Rat(this.zaehler, this.nenner);
		}
		else
			System.exit(1);
			return new Rat();
	}
}
```

nun rechne ich mit dieser klasse:

```
public class TestZahl {
  public static void main(String[] args) {
    Zahl[] r = new Rat[2];
    r[0] = new Rat(5,1);
    r[1] = new Rat(2,1);
     Zahl e = (r[0].div(r[1]));
      System.out.println(e);
  }
}
```

hierbei müsste ja nun 5/2 rauskommen, konsole zeigt aber 0/0 an ( das tut es auch bei egal welchem anderen wert).


----------



## MoD (16. Jan 2010)

Sollen nach der Aufgabenstellung eigentlich die das Feld r vor oder nach der Berechnung ausgegeben werden?
Ich habe nun das Bubblesort-Verfahren angewandt und folgendes Problem:
Wenn ich nach der Rechnung das Feld r sortiere, dann sortiert er die Zahlen aus der Rechnung.
Wenn ich das Sortieren vor der Berechnung ausführe, dann werden meine r[0], r[1] usw. durcheinander gewürfelt und mit diesem durchgewürfelten Zahlen geht er dann in die Rechnung.

Kann ich das Feld nicht irgendwie schützen vor der "durchwürfelung" oder es als eine "Sicherheitskopie" irgendwo speichern und dieses sortieren oder damit rechnen?!?


----------



## Thömmas (16. Jan 2010)

also ich hab ganz einfach so gelöst:


```
public static void sort(Zahl[] k) {
        java.util.Arrays.sort(k);
    }
```

Allerdings gilt hier auch erst rechnen und dann sortieren weils sonst nur probleme gibt


----------



## JustinCredible (16. Jan 2010)

Wenn du diesen "fertigen" Sortier-Algorithmus benutzt, musst du deinem Hiwi aber auch erklären, wie er funktioniert und was er macht 
Wurde mir zumindest so gesagt...


----------



## Thömmas (16. Jan 2010)

hmm.. davon hab ich noch nix gehört.


----------



## MoD (16. Jan 2010)

na ob nun fertiger methode oder mit selbstprogrammierten bubblesort ist ja erstmal egal.
gibts denn eine möglichkeit das feld zu duplizieren und dieses überschreiben der felder vor dem rechnen zu umgehen?


----------



## addu (16. Jan 2010)

ob du dann dein selbst geschriebenes sortierverfahren oder den schon "fertigen" Sortieralgorithmus benutzt müsste dann im prinzip das selbe sein, ausser evtl in details. würds aber trotzdem selber machen 

wie auch immer, kann mir jemand sagen warum bei meiner Rat class immer 0/0 ausgegeben wird?


----------



## eRaaaa (16. Jan 2010)

Jepp, weil du in deinem Konstruktor den Zähler garnicht setzt!

```
public Rat(long zaehler, long nenner) {
	this.nenner = nenner;
    }
```

==>


```
public Rat(long zaehler, long nenner) {
	this.nenner = nenner;
	this.zaehler = zaehler;
    }
```


----------



## Marco13 (16. Jan 2010)

Leuchtturm hat gesagt.:


> Ich hab jetzt mal ne Lösung fürs addieren von nem Kommilitonen ders eigentlich drauf hat.
> ...



Auch @Landei: 

Wie gesagt, mit "instanceof" geht das eigentlich, aber ... "instanceof" ist eigentlich fast immer unschön. (Dazu wollte ich eigentlich schonmal einen Philosophier-Thread eröffnen....)

Stell' dir z.B. vor, du hättest die Aufgabe gehabt, Rationale und Natürliche Zahlen zu behandeln. Dann hättest du in der add-Methode der "Rat"-Klasse sowas geschrieben wie

```
if      (other instanceof Rat) addiereRationaleZahl();
else if (other instanceof Nat) addiereNatürlicheZahl();
else System.out.println("Das geht nicht!");
```
Und jetzt stell' dir vor, nachträglich wären noch die Ganzen Zahlen dazugekommen - dann würde der Versuch,
[c]rationaleZahl.add(ganzeZahl);[/c]
auszuführen, bewirken, dass "das geht nicht" ausgegeben wird, obwohl man ja sehr wohl eine Ganze Zahl zu einer Rationalen Zahl addieren kann!

Rauszufinden, an _welchen_ Stellen man dann _was_ ändern muss, damit das alles passt, wäre ziemlich ätzend - hier müßte man halt noch so eine Zeile wie
[c]else if (other instanceof Ganz) addiereGanzeZahl();[/c]
einfügen, aber wenn an 10 Stellen "instanceof" steht, wird das ein riesen-Gemurkse.

In jedem Fall sollte man also zumindest versuchen, das "instanceof" ... einzugrenzen. In diesem Fall wäre eine Option (vielleicht nicht die beste, aber eben EINE), dass man z.B. in "Rat" einen Konstruktor anbietet

```
private Rat(Zahl other)
{
    ...
}
```
und NUR dort die instanceof-Prüfungen macht. Dann könnte man in den ganzen add/sub... Methoden sowas machen wie


```
public Zahl add(Zahl zahl)
    {
        Rat rat = new Rat(zahl); // Hier drin finden alle relevanten instanceof-Tests statt...
        ...
```




Viel schlimmer ist aber, dass die vorgeschlagene Methode eigentlich "falsch" ist: Man KANN ja eine Rationale Zahl zu einer Natürlichen Zahl addieren! Das Ergebnis ist dann eine Rationale Zahl. Bei so einer Rechnug wie [c]1/2 + 3[/c] kommt eben [c]7/2[/c] raus!

(Die gleiche Schwäche tritt auch beim zuletzt geposteten Ansatz für [c]compare[/c] auf: Man kann natürlich sagen, ob [c]3[/c] größer oder kleiner ist als [c]3/2[/c]!)

Eine Abhilfe wäre eben "Ganz" und "Nat" von "Rat" erben zu lassen: Jede Natürliche oder Ganze Zahl ist auch eine Rationale Zahl! (Nochmal: Lishkov könnte einem da einen Strich durch die Rechnung machen, aber das macht die ja oft ...  )



Insgesamt ist das ja ähnlich wie bei den Rechnungen in Java selbst:
int + int = int
float + int = float
double + int = double
float + float = float
...
Es wird immer der "mächtigste" Datentyp zurückgegeben (Websuche "Java widening conversion" usw.)

Ähnlich _sollte_ es IMHO auch hier sein:
Nat + Nat = Nat
Nat + Ganz = Ganz
Nat + Rat = Rat
...

Und "compareTo" sollte IMMER funktionieren.


Das ganze ist IMHO nicht so trivial. Natürlich muss man für so eine Uni-Aufgabe nicht "die perfekte Lösung" finden, aber ... so gesehen ist es ja ganz schön, um "die Grenzen auszuloten", und zu sehen, WER sich WIE viele Gedanken zu solchen Sachen macht 


EDIT: Und um das nochmal zu betonen:
Bei so einer Rechnug wie [c]1/2 + 3[/c] kommt [c]7/2[/c] raus, und 
bei so einer Rechnug wie [c]3 + 1/2[/c] kommt AUCH [c]7/2[/c] raus...


----------



## Leuchtturm (16. Jan 2010)

Das ist echt interessant Marco aber für Anfänger wie mich ist die Aufgabe so schon schwer genug.

Ich versuch erstmal das so einfach wie möglich hinzubekommen damit ich es auch selbst noch verstehe und dann mal gucken ob noch Zeit bleibt sich mit diesen Problemen zu beschäftigen.

Ich glaub auch garnicht das eine gemischte rechnung unbedingt gefordert ist.?!!


----------



## Leuchtturm (16. Jan 2010)

Ich hab noch ne Frage hierzu:


```
public Nat add(Zahl z) {
   Nat ausgabe = new Nat();
   if(z instanceof Nat) {
      Nat summand = (Nat) z;
      ausgabe = new Nat(this.wert_nat + summand.wert_nat);
   }
   else {
     System.out.println("Es können nur natürliche Zahlen zu natürlichen Zahlen addiert werden!");
     System.exit(1);
  }
  return ausgabe;
}
```

Was beweirkt dieses Nat ausgabe = new Nat() oder besser wieso darf man das einfach schreiben..?


----------



## addu (16. Jan 2010)

ah, danke eraa! jetzt funktioniert die class auch richtig! jetzt funktioneren alle methoden in einer class, leider nicht zwischen diesen, wie marco13 schon angemerkt hat. Hab grad versucht ne zahl der class nat mit ner zahl der class rat zu addieren, geht aber nicht.
Den Ansatz mit nat von ganz und ganz von rat erben zu lassen finde ich gut und werde ich acuh mal probieren, allerdings soll das genannte array sortiert werden und da hab ich auch ein problem:


```
abstract class Zahl implements Comparable {
	abstract public Zahl add(Zahl z);
	abstract public Zahl sub(Zahl z);
	abstract public Zahl mul(Zahl z);
	abstract public Zahl div(Zahl z);
	abstract public int compareTo(Object k);
	public static void sort(Zahl[] k) {
		int i, j, z;
		
		for (i = 0; i < k.length; i++)
			for (j = i + 1; j < k.length - 1; j++)
				if (k[i] > k[j]){
					z = k[i]; k[i] = k[j]; k[j] = z;
				}
	}
}
```

eclipse sagt mir dann aber:


> The operator > is undefined for the argument type(s) Zahl, Zahl (Zeile 12)


und 


> -Type mismatch: cannot convert from int to Zahl
> -Type mismatch: cannot convert from Zahl to int



ich habe aber gedacht, dass durch die methode _compareTo_ die ich ja in den class Rat, Nat und Ganz konkretisiert habe, Zahl nun verglichen werden könnte !
hier mal aus Nat:

```
public int compareTo(Object k) {
		if (k instanceof Nat) {
			Nat n = (Nat) k;
			if (this.n < n.n) {
				return -1;
			} 
			else if (this.n > n.n) {
				return 1;
			} 
			else
				return 0;
		} 
		else
			System.exit(1);
			return 2;
	}
```


----------



## Leuchtturm (16. Jan 2010)

Hiermit kannst du das arry sortieren


```
public static void sort(Zahl[] k) {
      boolean sorted;
    do {
      sorted = true;
      for (int i = 0; i < k.length - 1; ++i) {
        if (k[i].compareTo(k[i + 1]) > 0) {
          Comparable tmp = k[i];
          k[i] = k[i + 1];
          k[i + 1] = (Zahl) tmp;
          sorted = false;
        }
      }
    } while (!sorted);
  }
```


----------



## heoyeah (16. Jan 2010)

Leuchtturm hat gesagt.:


> Hiermit kannst du das arry sortieren
> 
> 
> ```
> ...



Das funktioniert nicht richtig, weil nur nach Zähler sortiert wird.


----------



## Leuchtturm (16. Jan 2010)

also bei mir sortiert er richtig : 

Sortiert: -3/7 1/17 2/9 1/3 5/6


----------



## addu (16. Jan 2010)

heoyeah hat gesagt.:


> Das funktioniert nicht richtig, weil nur nach Zähler sortiert wird.



wie er unterscheidet was größer bzw kleiner ist, legst du in der methode _compareTo_ fest. d.h. da stimmt bei dir (und bei mir übrigens auch) was nicht.


----------



## GeorgM (16. Jan 2010)

hi, kann mir mal bitte einer sagen mit welchem Befehl in der Testdatei ich das feld sortieren lassen kann...


----------



## Leuchtturm (16. Jan 2010)

Zum Beispiel so:


```
System.out.println("Zahlen Sortiert:");
  Zahl.sort(r);
  for (Zahl z : r) {
    System.out.print(" " +z);
  }
```


----------



## heoyeah (16. Jan 2010)

Könnte bitte jemand die compareTo() methode für rationale zahlen posten?


----------



## Landei (16. Jan 2010)

[edit] Ach, das hat oben schon jemand gesehen...


----------



## Leuchtturm (17. Jan 2010)

tipp für die compareto methode:


```
public int compareTo(Object k) {
    if(k instanceof Rat) {
      Rat n = (Rat) k;
      long t_zaehler = this.zaehler * n.nenner;
      long n_zaehler = n.zaehler * this.nenner;
      if(t_zaehler < n_zaehler) {
        return -1;

usw...
```


----------



## hanky (17. Jan 2010)

Hallo,

hat einer schon von euch die Summe gebildet? ich habe bis jetzt das hier. Die add Methode funktioniert leider nicht und ich weis nicht wieso.

Es gibt diese 2 Fehlermedungen
r cannot be resolved or is not a field
Syntax error on token ad

[Java]
public Zahl summe(Zahl z){

      long a = 1, b = 1; int i =0;
	  Zahl[] r = new Rat[5];
	    r_ = new Rat(a,b);
	    if (i<20){
	    i++;
	    b++;
	    r = new Rat(a,b);
	    }
	    Zahl t = (r[1]add.r[2]);
	    return t;[/Java]

Bis jetzt habt ihr mir schon super geholfen. Danke!_


----------



## MoD (17. Jan 2010)

Ja es wäre echt sehr geil, wenn hier jemand bei der Summenformel helfen kann


----------



## addu (17. Jan 2010)

```
int i, j;
	  Zahl[] s = new Rat[22];
	  for(i = 0; i < 21; i++) {
		  s[i] = new Rat(1,i+1);
	  }

	  for(j = 0; j < 21; j++){ 
		 Zahl d = s[j].add(s[j+1]);
		 System.out.println(d);
	  }
```


----------



## eRaaaa (17. Jan 2010)

addu hat gesagt.:


> ```
> int i, j;
> Zahl[] s = new Rat[22];
> for(i = 0; i < 21; i++) {
> ...



Ich blicke hier zwar kaum noch durch, aber in deiner Lösung summierst du auch den Bruch 1/21 auf. Soll doch nur bis 1/20 aufsummiert werden?!


----------



## addu (17. Jan 2010)

sorry muss ja


```
int i, j;
	  Zahl[] s = new Rat[22];
	  for(i = 1; i < 21; i++) {
		  s[i-1] = new Rat(1,i);
	  }

	  for(j = 1; j < 21; j++){ 
		 Zahl d = s[j-1].add(s[j]);
		 System.out.println(d);
	  }
```
heissen.

ps: die berechnung funzt so nicht, es kommt was falsches raus.


----------



## hanky (17. Jan 2010)

Als Methode wie soll man das da adaptieren? Und es werden leider die 20 Summen alle ausgegeben. Und mit dem edit wurde nichts verändert.


----------



## bernd0815 (17. Jan 2010)

so habe ich die summenbildung getestet, leider habe ich keine ahnung, wie man die brüche abrunden soll, daher kommt ein sehr hohes ergebnis raus.
wie kürzt ihr eure brüche?

```
public class TestSumme {
  public static void main(String[] args) {
    Zahl[] r = new Rat[21];
    r[0]=new Rat(1,1); //wird nicht benötigt;
    int i;
    for (i=1;i<=20;i++) {
      r[i]= new Rat(1,i);
    }
    for(i=1;i<=19;i++) {
      Zahl e = r[i].add(r[i+1]);
    }
    System.out.println(e);
  }
}
```


----------



## Leuchtturm (17. Jan 2010)

Das mit der Summe berechnen habt ihr aber schon in die Test Datei geschrieben oder??

hohe ergebnis kommt bei mir auch raus:

 55835135/15519504


----------



## hanky (17. Jan 2010)

ja, aber es wurden alle zwischenergebnisse mitausgegeben und ich war nicht in der Lage es abzustellen.

@ bernd guck mal in Post 5 da ist das mithilfe zweier Methoden gelöst (kueren ung getggt)


----------



## MoD (17. Jan 2010)

addu hat gesagt.:


> sorry muss ja
> 
> 
> ```
> ...



Das gibt falsche Werte aus.
Gleich schreib ich in mein TestZahl.java einfach das rein:


```
double i, j = 0;
  for (i = 1; i < 21; i++) {
    j += 1/i;
    System.out.println(j);
  }
```


----------



## hanky (17. Jan 2010)

bernd0815 hat gesagt.:


> so habe ich die summenbildung getestet, leider habe ich keine ahnung, wie man die brüche abrunden soll, daher kommt ein sehr hohes ergebnis raus.
> wie kürzt ihr eure brüche?
> 
> ```
> ...



e cannot be resolved


----------



## MoD (17. Jan 2010)

Leuchtturm hat gesagt.:


> Das mit der Summe berechnen habt ihr aber schon in die Test Datei geschrieben oder??
> 
> hohe ergebnis kommt bei mir auch raus:
> 
> 55835135/15519504



Poste mal bitte deine Summen-Lösung


----------



## hanky (17. Jan 2010)

39,380 aber kA ob es genau stimmt.


----------



## MoD (17. Jan 2010)

hanky hat gesagt.:


> 39,380 aber kA ob es genau stimmt.



55835135/15519504 = 3,597739657143682 

Stimmt schon.


----------



## Leuchtturm (17. Jan 2010)

Nicht vergessen:



> Sortieren Sie dann das Feld r mit der Methode sort und geben Sie das sortierte Feld aus.
> Berechnen Sie *anschließend* mit Ihrem Programm den genauen Wert der Summe


----------



## MoD (17. Jan 2010)

Leuchtturm hat gesagt.:


> Nicht vergessen:
> 
> 
> 
> ...



Ja? Also steht in meiner Test main Methode:
- rechnen
- ausgabe
- sortieren
- summe berechnen

Kannst du vielleicht deine Summenformel posten?


----------



## Leuchtturm (17. Jan 2010)

oki ich will mal nicht so sein 


```
Zahl[] s = new Rat[20];
  for(int i = 0; i <= s.length-1; i++) {
    s[i] = new Rat(1,i+1);
  }
  Zahl bruch = s[0];
  for(int i = 1; i <= s.length-1; i++) {
    bruch = bruch.add(s[i]);  // ergebnis als bruch
  }
  Rat zw = (Rat) bruch;
  double dezimalbruch = (double) zw.zaehler / (double) zw.nenner; // ergebnis als dezimalbruch
```


----------



## Bernd0815 (17. Jan 2010)

MoD hat gesagt.:


> 55835135/15519504 = 3,597739657143682
> 
> Stimmt schon.



also 
3,597739657143682 kommt bei mir auch heraus, bloß als bruch eben:
8752948036761600000/2432902008176640000
xD

und wenn ich die methoden kuerzen() und ggt mit einbaue kommt zwar kein kompilierungsfehler, aber es erscheint kein ergebnis wenn ich Test starte...


----------



## hanky (17. Jan 2010)

wie habt ihr das eingebunden? Als Methode oder in der Testklasse?


----------



## Leuchtturm (17. Jan 2010)

hanky hat gesagt.:


> wie habt ihr das eingebunden? Als Methode oder in der Testklasse?



inna testklasse nach der Summe!


----------



## hanky (17. Jan 2010)

Da klappt bei mir die Umrechnung in den double Wert nicht mehr.


----------

