import java.math.BigInteger;
/**
* @author Paul Keller
* @version 1.0
* @date 20.11.2017
*/
public final class Fraction extends Number implements Comparable<Fraction>
{
private BigInteger zähler;
private BigInteger nenner;
public static final Fraction NaN = new Fraction(BigInteger.ZERO,BigInteger.ZERO);
public Fraction(BigInteger zähler, BigInteger nenner) {
this.zähler=zähler;
this.nenner=nenner;
kürzen();
if(this.zähler.compareTo(BigInteger.ZERO)<0&&this.nenner.compareTo(BigInteger.ZERO)<0)
{
this.zähler=this.zähler.abs();
this.nenner=this.nenner.abs();
}
else if(this.nenner.compareTo(BigInteger.ZERO)<0)
{
this.zähler=this.zähler.multiply(BigInteger.valueOf(-1));
this.nenner=this.nenner.abs();
}
}
public Fraction (long zähler, long nenner)
{
this(BigInteger.valueOf(zähler),BigInteger.valueOf(nenner));
}
public BigInteger getNenner()
{
return nenner;
}
public BigInteger getZähler()
{
return zähler;
}
public Fraction add(Fraction r)
{
if(isNaN(this)||isNaN(r))
{
return NaN;
}
BigInteger kgv = calckgv(nenner,r.nenner);
BigInteger zähler1 = kgv.divide(nenner).multiply(zähler);
BigInteger zähler2 = kgv.divide(r.nenner).multiply(r.zähler);
BigInteger zählerE= zähler1.add(zähler2);
return new Fraction(zählerE, kgv);
}
private BigInteger calckgv(BigInteger x, BigInteger y)
{
if(x.compareTo(y)>=0)
{
return(x.multiply(y).divide(x.gcd(y)));
}
else
return (y.multiply(x).divide(y.gcd(x)));
}
public void kürzen()
{
if(isNaN(this)) {
this.nenner = BigInteger.ZERO;
this.zähler=BigInteger.ZERO;
}else {
BigInteger gcd = zähler.gcd(nenner);
zähler = zähler.divide(gcd);
nenner = nenner.divide(gcd);
}
}
public Fraction subtract(Fraction r)
{
if(isNaN(this)||isNaN(r))
{
return NaN;
}
BigInteger kgv = calckgv(nenner,r.nenner);
BigInteger zähler1 = kgv.divide(nenner).multiply(zähler);
BigInteger zähler2 = kgv.divide(r.nenner).multiply(r.zähler);
BigInteger zählerE= zähler1.subtract(zähler2);
return new Fraction(zählerE, kgv);
}
public Fraction multiply (Fraction r)
{
if(isNaN(this)||isNaN(r))
{
return NaN;
}
return new Fraction(zähler.multiply(r.zähler),nenner.multiply(r.nenner));
}
public Fraction divide(Fraction r)
{
if(isNaN(this)||isNaN(r))
{
return NaN;
}
return new Fraction(zähler.multiply(r.nenner),nenner.multiply(r.zähler));
}
public String toString()
{
String z = zähler.toString();
int modulo = zähler.toString().length()%3;
z=(modulo==0?"":z.substring(0,modulo));
for(int i=modulo;i<zähler.toString().length();i+=3)
{
if(i!=0)
z=z+"."+zähler.toString().substring(i,i+3);
else
{
z=z+zähler.toString().substring(i,i+3);
}
}
String s = (nenner.compareTo(BigInteger.ONE)==0?z:z+"/"+nenner.toString());
return s;
}
public boolean isInteger()
{
return nenner.equals(BigInteger.ONE);
}
public int compareTo(Fraction o) {
if(isNaN(this)&&isNaN(o))
{
return 0;
}
else if(isNaN(this))
{
return 1;
}
else if(isNaN(o))
{
return -1;
}
else
{
BigInteger zähler1 = o.nenner.multiply(zähler);
BigInteger zähler2 = nenner.multiply(o.zähler);
return zähler1.compareTo(zähler2);
}
}
@Override
public int intValue() {
return zähler.intValue()/nenner.intValue();
}
private boolean isNaN(Fraction fraction) {
if(fraction.nenner.compareTo(BigInteger.ZERO)==0)
{
return true;
}
return false;
}
@Override
public long longValue() {
return zähler.divide(nenner).longValue();
}
@Override
public float floatValue() {
if(isNaN(this))
{
return Float.NaN;
}
return zähler.floatValue()/nenner.floatValue();
}
@Override
public double doubleValue() {
if(isNaN(this))
{
return Double.NaN;
}
return zähler.doubleValue()/nenner.doubleValue();
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Fraction)
{
return (nenner.equals(((Fraction)obj).nenner)&&zähler.equals(((Fraction)obj).zähler));
}
return false;
}
}