Skip to content

Instantly share code, notes, and snippets.

@FlorianCassayre
Created March 4, 2017 18:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FlorianCassayre/b12544a450ee67b3c142cb6562a3cb1e to your computer and use it in GitHub Desktop.
Save FlorianCassayre/b12544a450ee67b3c142cb6562a3cb1e to your computer and use it in GitHub Desktop.
import java.math.BigInteger;
public final class BigRational extends Number implements Comparable<BigRational>
{
public final static BigRational ZERO = valueOf(0);
public final static BigRational ONE = valueOf(1);
public final static BigRational MINUS_ONE = valueOf(-1);
private BigInteger numerator;
private BigInteger denominator;
public BigRational(BigInteger numerator, BigInteger denominator)
{
if(denominator.equals(BigInteger.ZERO))
throw new ArithmeticException();
this.numerator = numerator;
this.denominator = denominator;
reduce();
}
public BigRational(BigInteger numerator)
{
this(numerator, BigInteger.ONE);
}
public BigRational()
{
this(BigInteger.ZERO);
}
private void reduce()
{
boolean sign = false;
if(numerator.signum() >= 0 ^ denominator.signum() >= 0)
{
sign = true;
}
else
{
if(numerator.equals(BigInteger.ZERO))
{
denominator = BigInteger.ONE;
}
}
numerator = numerator.abs();
denominator = denominator.abs();
if(sign)
{
numerator = numerator.multiply(BigInteger.valueOf(-1));
}
final BigInteger divisor = pgcd(numerator.abs(), denominator);
if(!divisor.equals(BigInteger.ONE))
{
numerator = numerator.divide(divisor);
denominator = denominator.divide(divisor);
}
}
@Override
public int intValue()
{
return numerator.intValue() / denominator.intValue();
}
@Override
public long longValue()
{
return numerator.longValue() / denominator.longValue();
}
@Override
public float floatValue()
{
return numerator.floatValue() / denominator.floatValue();
}
@Override
public double doubleValue()
{
return numerator.doubleValue() / denominator.doubleValue();
}
public static BigRational valueOf(long num, long denom)
{
return new BigRational(BigInteger.valueOf(num), BigInteger.valueOf(denom));
}
public static BigRational valueOf(long num)
{
return valueOf(num, 1);
}
public BigInteger getNumerator()
{
return numerator;
}
public BigInteger getDenominator()
{
return denominator;
}
public BigRational add(BigRational n)
{
BigInteger num1 = numerator, denom1 = denominator, num2 = n.numerator, denom2 = n.denominator;
num1 = num1.multiply(denom2);
num2 = num2.multiply(denom1);
BigInteger denom = denom1.multiply(denom2);
return new BigRational(num1.add(num2), denom);
}
public BigRational substract(BigRational n)
{
return add(new BigRational(n.numerator.multiply(BigInteger.valueOf(-1)), n.denominator));
}
public BigRational multiply(BigRational n)
{
BigInteger num1 = numerator, denom1 = denominator, num2 = n.numerator, denom2 = n.denominator;
num1 = num1.multiply(num2);
denom1 = denom1.multiply(denom2);
return new BigRational(num1, denom1);
}
public BigRational divide(BigRational n)
{
return multiply(new BigRational(n.denominator, n.numerator));
}
public BigRational reciprocal()
{
return ONE.divide(this);
}
public boolean isInteger()
{
return denominator.equals(BigInteger.ONE);
}
public boolean isOne()
{
return numerator.equals(denominator);
}
public BigRational abs()
{
return new BigRational(numerator.abs(), denominator);
}
public BigRational pow(int n)
{
BigRational b = ONE;
for(int i = 0; i < n; i++)
{
b = b.multiply(this);
}
return b;
}
private BigInteger pgcd(BigInteger a, BigInteger b)
{
BigInteger r;
while(!b.equals(BigInteger.ZERO))
{
r = a.mod(b);
a = b;
b = r;
}
return a;
}
@Override
public String toString()
{
return numerator.toString() + "/" + denominator.toString();
}
@Override
public int hashCode()
{
return toString().hashCode(); // Since there is one unique string representation, this should be unique too.
}
@Override
public boolean equals(Object object)
{
if(object instanceof BigRational)
{
BigRational n = (BigRational) object;
if(numerator.equals(n.numerator) && denominator.equals(n.denominator))
return true;
}
return false;
}
@Override
public int compareTo(BigRational o)
{
BigInteger a = numerator.multiply(o.denominator);
BigInteger b = denominator.multiply(o.numerator);
return a.compareTo(b);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment