package net.sf.orcc.util; public class Rational implements Comparable<Rational> { private static Rational zero = new Rational(0, 1); public static int gcd(int m, int n) { if (0 == n) { return m; } else { return gcd(n, m % n); } } public static int lcm(int m, int n) { return m * (n / gcd(m, n)); } private int denominator; private int numerator; public Rational(int numerator, int denominator) { int g = gcd(numerator, denominator); this.numerator = numerator / g; this.denominator = denominator / g; if (this.denominator < 0) { this.denominator = -this.denominator; this.numerator = -this.numerator; } } public int compareTo(Rational b) { Rational a = this; int lhs = a.numerator * b.denominator; int rhs = a.denominator * b.numerator; if (lhs < rhs) return -1; if (lhs > rhs) return +1; return 0; } // return a / b public Rational div(Rational b) { return this.mul(b.reciprocal()); } public boolean equals(Object y) { if (y == null) return false; if (y.getClass() != this.getClass()) return false; Rational b = (Rational) y; return compareTo(b) == 0; } public int getDenominator() { return denominator; } public int getNumerator() { return numerator; } // return a - b public Rational sub(Rational b) { return this.add(b.negate()); } // return -a public Rational negate() { return new Rational(-numerator, denominator); } public Rational add(Rational b) { if (this.compareTo(zero) == 0) { return b; } if (b.compareTo(zero) == 0) { return this; } // Find gcd of numerators and denominators int f = gcd(numerator, b.numerator); int g = gcd(denominator, b.denominator); // add cross-product terms for numerator Rational s = new Rational((numerator / f) * (b.denominator / g) + (b.numerator / f) * (denominator / g), lcm(denominator, b.denominator)); // multiply back in s.numerator *= f; return s; } public Rational reciprocal() { return new Rational(denominator, numerator); } public Rational mul(Rational b) { Rational c = new Rational(numerator, b.denominator); Rational d = new Rational(b.numerator, denominator); return new Rational(c.numerator * d.numerator, c.denominator * d.denominator); } public double toDouble() { return (double) numerator / denominator; } public String toString() { if (denominator == 1) return numerator + ""; else return numerator + "/" + denominator; } }