import java.math.BigInteger;
/**
* This is a class of immutible object that support extended-precision
* rational arithmetic. All of the usual arithmetic operations are
* supported.
*/
public class BigFraction
{
/**
* This is the BigFraction 0/1
*/
public final static BigFraction ZERO;
/**
* This is the BigFraction 0/1
*/
public final static BigFraction ONE;
/**
* This is the BigFraction 1/2
*/
public final static BigFraction HALF;
//static block.
static
{
ZERO = new BigFraction();
ONE = BigFraction.valueOf(1,1);
HALF = BigFraction.valueOf(1,2);
}
private final BigInteger num;
private final BigInteger denom;
/**
* This creates a BigFraction with the specified numerator and
* denominator
* @param num this is the numerator we are specifying
* @param denom this is the denominator we are specifying
*/
public BigFraction(BigInteger num, BigInteger denom)
{
if(denom.equals(BigInteger.ZERO))
{
throw new IllegalArgumentException();
}
BigInteger d = denom.gcd(num);
num = num.divide(d);
denom = denom.divide(d);
if(denom.compareTo(BigInteger.ZERO) < 0)
{
num = num.negate();
denom = denom.negate();
}
this.num = num;
this.denom = denom;
}
/**
* This creates the BigFraction 0/1, which is the same as BigFraction.ZERO.
*/
public BigFraction()
{
this(BigInteger.ZERO, BigInteger.ONE);
}
/**
* This gives a string represention of the form numerator/denominator.
* @return a string representation of the form numerator/denominator.
*/
@Override
public String toString()
{
return String.format("%s/%s", num, denom);
}
/**
* This checks if this BigFraction has the same numerical value as
* the object o.
* @param o the object we are comparing this BigFraction to.
* @return true if o is a BigFraction and if it is numerically
* equal to this BigFraction
*/
@Override
public boolean equals(Object o)
{
if(o == this)
{
return true;
}
//species test
if( !(o instanceof BigFraction))
{
return false;
}
BigFraction that = (BigFraction) o;
return num.equals(that.num) && denom.equals(that.denom);
}
/**
* This computes this + that.
* @param that the BigFraction we are adding this BigFraction to.
* @return this + that
*/
public BigFraction add(BigFraction that)
{
BigInteger top = num.multiply(that.denom).add(denom.multiply(that.num));
BigInteger bottom = denom.multiply(that.denom);
return new BigFraction(top, bottom);
}
/**
* This computes this - that.
* @param that the BigFraction we are subtracting this BigFraction from.
* @return this - that
*/
public BigFraction subtract(BigFraction that)
{
BigInteger top = num.multiply(that.denom).subtract(denom.multiply(that.num));
BigInteger bottom = denom.multiply(that.denom);
return new BigFraction(top, bottom);
}
/**
* This computes this*that.
* @param that the BigFraction we are multiplying this BigFraction by.
* @return this*that
*/
public BigFraction multiply(BigFraction that)
{
BigInteger top = num.multiply(that.num);
BigInteger bottom = denom.multiply(that.num);
return new BigFraction(top, bottom);
}
/**
* This computes this/that.
* @param that the BigFraction we are dividing this BigFraction by.
* @return this/that
*/
public BigFraction divide(BigFraction that)
{
BigInteger top = num.multiply(that.denom);
BigInteger bottom = denom.multiply(that.num);
return new BigFraction(top, bottom);
}
/**
* This is a static factory method that allows a BigFraction to
* specified by longs in the numerator and the denominator.
* @param num the numerator we are specifying
* @param denom the denominator we are specifying
* @return the BigFraction num/denom.
*/
public static BigFraction valueOf(long num, long denom)
{
return new BigFraction(BigInteger.valueOf(num), BigInteger.valueOf(denom));
}
/*
* This is where test code is dumped.
*/
public static void main(String[] args)
{
BigFraction boo = BigFraction.valueOf(3,4);
System.out.println(boo);
boo = BigFraction.valueOf(-3, -4);
System.out.println(boo);
boo = BigFraction.valueOf(6,8);
System.out.println(boo);
boo = BigFraction.valueOf(1048576, 7776);
System.out.println(boo);
BigFraction total = new BigFraction();
for(long k = 1; k <= 1000; k++)
{
total = total.add(BigFraction.valueOf(1, k));
}
System.out.println(total);
}
}