I’m trying to work with fractions in Java.
I want to implement arithmetic functions. For this, I will first require a way to normalize the functions. I know I can’t add 1/6 and 1/2 until I have a common denominator. I will have to add 1/6 and 3/6. A naive approach would have me add 2/12 and 6/12 and then reduce. How can I achieve a common denominator with the least performance penalty? What algorithm is best for this?
Version 8 (thanks to hstoerr):
Improvements include:
- the equals() method is now consistent with the compareTo() method
final class Fraction extends Number { private int numerator; private int denominator; public Fraction(int numerator, int denominator) { if(denominator == 0) { throw new IllegalArgumentException('denominator is zero'); } if(denominator < 0) { numerator *= -1; denominator *= -1; } this.numerator = numerator; this.denominator = denominator; } public Fraction(int numerator) { this.numerator = numerator; this.denominator = 1; } public int getNumerator() { return this.numerator; } public int getDenominator() { return this.denominator; } public byte byteValue() { return (byte) this.doubleValue(); } public double doubleValue() { return ((double) numerator)/((double) denominator); } public float floatValue() { return (float) this.doubleValue(); } public int intValue() { return (int) this.doubleValue(); } public long longValue() { return (long) this.doubleValue(); } public short shortValue() { return (short) this.doubleValue(); } public boolean equals(Fraction frac) { return this.compareTo(frac) == 0; } public int compareTo(Fraction frac) { long t = this.getNumerator() * frac.getDenominator(); long f = frac.getNumerator() * this.getDenominator(); int result = 0; if(t>f) { result = 1; } else if(f>t) { result = -1; } return result; } }
I have removed all previous versions. My thanks to:
It just so happens that I wrote a BigFraction class not too long ago, for Project Euler problems. It keeps a BigInteger numerator and denominator, so it’ll never overflow. But it’ll be a tad slow for a lot of operations that you know will never overflow.. anyway, use it if you want it. I’ve been dying to show this off somehow. 🙂
Edit: Latest and greatest version of this code, including unit tests is now hosted on GitHub and also available via Maven Central. I’m leaving my original code here so that this answer isn’t just a link…