226 lines
4.4 KiB
Java
226 lines
4.4 KiB
Java
package mathe;
|
|
|
|
/**
|
|
* Bearbeitung von Brüchen.
|
|
*
|
|
* @author Daniel Weschke
|
|
*
|
|
*/
|
|
public class Bruch{
|
|
int zähler;
|
|
int nenner;
|
|
|
|
/**
|
|
* Bruch mit Nenner 1.
|
|
*/
|
|
public Bruch(){
|
|
nenner = 1;
|
|
}
|
|
|
|
/**
|
|
* Bruch mitübergebenen zähler und Nenner 1.
|
|
*
|
|
* @param z zähler
|
|
*/
|
|
public Bruch(int z){
|
|
this();
|
|
zähler = z;
|
|
}
|
|
|
|
/**
|
|
* Bruch mitübergebenen zähler und Nenner.
|
|
*
|
|
* @param z zähler
|
|
* @param n Nenner
|
|
*/
|
|
public Bruch(int z, int n){
|
|
this(z);
|
|
if(n>0) nenner = n;
|
|
}
|
|
|
|
/**
|
|
* Custom Constructor, der aus einer Gleitkommazahl einen Bruch ermittelt.
|
|
* Um Rundungsfehler zu vermeiden wird der Bruch ueber die Stringdarstellung der Gleitkommazahl ermittelt.
|
|
* @param gleitKommaZahl Zahl, die in einen Bruch umgewandelt werden soll.
|
|
*/
|
|
public Bruch(double gleitKommaZahl) {
|
|
|
|
// Damit keine Rundungsfehler auftreten die Zahl in einen String wandeln
|
|
String ds = "" + gleitKommaZahl;
|
|
|
|
// String am Punkt splitten
|
|
// Achtung: Beim Splitten ist der Punkt ein Sonderzeichen,
|
|
// daher der Umweg ueber ein "beliebiges" Zeichen (hier "p")
|
|
ds = ds.replace(".", "p");
|
|
String[] sa = ds.split("p");
|
|
|
|
// Zaehler und Nenner bestimmen
|
|
nenner = (int) Math.pow(10, sa[1].length());
|
|
zähler = (int) (gleitKommaZahl * nenner);
|
|
|
|
// Den Bruch kuerzen
|
|
int faktor = ggt_fast(zähler, nenner);
|
|
nenner /= faktor;
|
|
zähler /= faktor;
|
|
|
|
// Die Assertion prueft, ob der Nenner != 0 ist.
|
|
// Falls die Auswertung true ergibt ist alles OK
|
|
assert nenner != 0 : "Division durch 0!";
|
|
|
|
// Testen, ob das Ergebnis stimmt oder ob Rundungsfehler vorhanden sind
|
|
assert 1.0 * zähler / nenner == gleitKommaZahl : "Rundungsfehler!!";
|
|
}
|
|
|
|
/**
|
|
* Addition zweier Brüche.
|
|
*
|
|
* @param a zu addierender Bruch
|
|
* @return Summe
|
|
*/
|
|
public Bruch plus(Bruch a){
|
|
return new Bruch(zähler*a.nenner+a.zähler*nenner,nenner*a.nenner);
|
|
}
|
|
|
|
/**
|
|
* Subtraktion zweier Brüche.
|
|
*
|
|
* @param a zu subtrahierender Bruch
|
|
* @return Differenz
|
|
*/
|
|
public Bruch minus(Bruch a){
|
|
Bruch b = new Bruch(-a.zähler,a.nenner);
|
|
return this.plus(b);
|
|
}
|
|
|
|
/**
|
|
* Multikation zweier Brüche.
|
|
*
|
|
* @param a zu multiplizierder Bruch
|
|
* @return Produkt
|
|
*/
|
|
public Bruch mal(Bruch a){
|
|
return new Bruch(zähler*a.zähler,nenner*a.nenner);
|
|
}
|
|
|
|
/**
|
|
* Division zweier Brüche.
|
|
*
|
|
* @param a zu dividierender Bruch
|
|
* @return Verhältnis
|
|
*/
|
|
public Bruch durch(Bruch a){
|
|
return this.mal(a.kehrwert());
|
|
}
|
|
|
|
/**
|
|
* Kehrwert vom Bruch.
|
|
*
|
|
* @return Reziprok
|
|
*/
|
|
public Bruch kehrwert(){
|
|
return new Bruch(nenner,zähler);
|
|
}
|
|
|
|
/**
|
|
* Gößten gemeinsamen Teiler vom Bruch.
|
|
* Nach dem klassischen euklidischen Algorithmus.
|
|
*
|
|
* @return größten gemeinsamen Teiler
|
|
*/
|
|
public int ggt(){
|
|
int a = zähler<0 ? -zähler : zähler;
|
|
int b = nenner<0 ? -nenner : nenner;
|
|
if(a>0 && b>0){
|
|
while(a!=b){
|
|
if(a>b){
|
|
a = a - b;
|
|
} else {
|
|
b = b - a;
|
|
}
|
|
}
|
|
}
|
|
return a;
|
|
}
|
|
|
|
/**
|
|
* Größter gemeinsamer Teiler vom Bruch.
|
|
* Nach dem modernen euklidischen Algorithmus.
|
|
*
|
|
* @return größten gemeinsamen Teiler
|
|
*/
|
|
public int ggt_fast(){
|
|
int a = zähler<0 ? -zähler : zähler;
|
|
int b = nenner<0 ? -nenner : nenner;
|
|
int c;
|
|
if(a>0 && b>0){
|
|
while(b!=0){
|
|
c = a%b;
|
|
a = b;
|
|
b = c;
|
|
}
|
|
}
|
|
return a;
|
|
}
|
|
|
|
/**
|
|
* Größter gemeinsamer Teiler vom Bruch.
|
|
* Nach dem modernen euklidischen Algorithmus.
|
|
*
|
|
* @return größten gemeinsamen Teiler
|
|
*/
|
|
public int ggt_fast(int zähler, int nenner){
|
|
int a = zähler<0 ? -zähler : zähler;
|
|
int b = nenner<0 ? -nenner : nenner;
|
|
int c;
|
|
if(a>0 && b>0){
|
|
while(b!=0){
|
|
c = a%b;
|
|
a = b;
|
|
b = c;
|
|
}
|
|
}
|
|
return a;
|
|
}
|
|
|
|
/**
|
|
* Kürzen des Bruches.
|
|
*
|
|
* @return gekürzter Bruch
|
|
*/
|
|
public Bruch kürzen(){
|
|
if(zähler!=0 && nenner!=0)
|
|
return new Bruch(zähler/ggt(),nenner/ggt());
|
|
else
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Vergleich zweier Brüche.
|
|
*
|
|
* @param q zu vergleichender Bruch
|
|
* @return Bitcode:<br />
|
|
* <code> 1</code> Bruch ist größer<br />
|
|
* <code>-1</code> Bruch ist kleiner<br />
|
|
* <code> 0</code> Bruch ist gleich groß<br />
|
|
*/
|
|
public int compareTo(Bruch q){
|
|
double a = (double) zähler/nenner;
|
|
double b = (double) q.zähler/q.nenner;
|
|
if(a > b) return 1; else
|
|
if(a < b) return -1; else
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Textumwandlung zur Ausgabe.
|
|
*/
|
|
@Override
|
|
public String toString(){
|
|
Bruch a = this.kürzen();
|
|
if(a.nenner!=1)
|
|
return new String(a.zähler + "/" + a.nenner);
|
|
else
|
|
return new String(""+a.zähler);
|
|
}
|
|
}
|