Skip to content

Instantly share code, notes, and snippets.

@Sam-Belliveau
Last active March 11, 2020 18:48
Show Gist options
  • Save Sam-Belliveau/6ed1f75388ac5b33a680b05bc679b6b8 to your computer and use it in GitHub Desktop.
Save Sam-Belliveau/6ed1f75388ac5b33a680b05bc679b6b8 to your computer and use it in GitHub Desktop.
public class Rational extends Number implements Comparable<Rational> {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final int kCFLLength = 16;
private final long mN, mD;
private static long gcd(long a, long b) {
return (b == 0) ? a : gcd(b, a % b);
}
public Rational(long n, long d) {
if(d == 0) {
throw new RuntimeException("Division By 0!");
}
long factor = gcd(Math.abs(n), Math.abs(d));
mN = (n / factor) * ((d < 0) ? -1 : 1);
mD = (Math.abs(d) / factor);
}
public Rational(Rational other) {
this(other.getNumerator(), other.getDenominator());
}
public Rational(double num) {
// Continued fraction list
long[] cfl = new long[kCFLLength];
long cflMax = 0;
int iter = kCFLLength - 1;
// Store the sign of the original number
long sign = (long)(Math.signum(num));
num = Math.abs(num);
// Calculate continued fraction list
for(int i = 0; i < cfl.length; ++i) {
cfl[i] = (long)(Math.floor(num));
num -= cfl[i];
if(num != 0) {
num = Math.abs(1.0 / num);
} else {
iter = i;
break;
}
if(cfl[i] >= cflMax) {
cflMax = cfl[i];
iter = i;
}
}
// Calculate numerator and denominator
long n = 0, d = 1;
for(int i = iter; i >= 0; --i) {
long t = cfl[i] * n + d;
d = n;
n = t;
}
long factor = gcd(Math.abs(n), Math.abs(d));
mN = (n / factor) * ((d < 0) ? -1 : 1) * sign;
mD = (Math.abs(d) / factor);
}
public Rational(long num) {
this(num, 1);
}
public long getNumerator() {
return mN;
}
public long getDenominator() {
return mD;
}
public Rational add(Rational other) {
long n_a = this.getNumerator() * other.getDenominator();
long n_b = other.getNumerator() * this.getDenominator();
long d = this.getDenominator() * other.getDenominator();
return new Rational(n_a + n_b, d);
}
public Rational sub(Rational other) {
long n_a = this.getNumerator() * other.getDenominator();
long n_b = other.getNumerator() * this.getDenominator();
long d = this.getDenominator() * other.getDenominator();
return new Rational(n_a - n_b, d);
}
public Rational mul(Rational other) {
return new Rational(this.getNumerator() * other.getNumerator(), this.getDenominator() * other.getDenominator());
}
public Rational div(Rational other) {
return new Rational(this.getNumerator() * other.getDenominator(), this.getDenominator() * other.getNumerator());
}
@Override
public int intValue() {
return ((int) mN) / ((int) mD);
}
@Override
public long longValue() {
return ((long) mN) / ((long) mD);
}
@Override
public float floatValue() {
return ((float) mN) / ((float) mD);
}
@Override
public double doubleValue() {
return ((double) mN) / ((double) mD);
}
@Override
public int compareTo(Rational other) {
long n_a = this.getNumerator() * other.getDenominator();
long n_b = other.getNumerator() * this.getDenominator();
return (int)(Math.signum(n_a - n_b));
}
@Override
public String toString() {
return "[" + mN + " / " + mD + "]";
}
public static void main(String[] args) {
Rational a = new Rational(Math.sqrt(2));
Rational b = new Rational(Math.E);
System.out.println("a: " + a.doubleValue());
System.out.println("b: " + b.doubleValue());
System.out.println("a: " + a);
System.out.println("b: " + b);
System.out.println("a + b: " + a.add(b));
System.out.println("a - b: " + a.sub(b));
System.out.println("a * b: " + a.mul(b));
System.out.println("a / b: " + a.div(b));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment