Files
wscience/srcDE/mathe/Bruch.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);
}
}