diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index a62e0d7..9a969c9 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -310,19 +310,6 @@
     }
 
     /**
-     * Create a fraction given the numerator and denominator.
-     * The fraction is reduced to lowest terms.
-     *
-     * @param num the numerator.
-     * @param den the denominator.
-     * @return a new instance.
-     * @throws ArithmeticException if {@code den} is zero.
-     */
-    public static BigFraction of(final int num, final int den) {
-        return new BigFraction(BigInteger.valueOf(num), BigInteger.valueOf(den));
-    }
-
-    /**
      * Create a fraction given the numerator. The denominator is {@code 1}.
      *
      * @param num the numerator.
@@ -333,19 +320,6 @@
     }
 
     /**
-     * Create a fraction given the numerator and denominator.
-     * The fraction is reduced to lowest terms.
-     *
-     * @param num the numerator.
-     * @param den the denominator.
-     * @return a new instance.
-     * @throws ArithmeticException if {@code den} is zero.
-     */
-    public static BigFraction of(final long num, final long den) {
-        return new BigFraction(BigInteger.valueOf(num), BigInteger.valueOf(den));
-    }
-
-    /**
      * Create a fraction given the numerator. The denominator is {@code 1}.
      *
      * @param num the numerator.
@@ -363,13 +337,146 @@
      * @param num the numerator.
      * @param den the denominator.
      * @return a new instance.
+     * @throws ArithmeticException if {@code den} is zero.
+     */
+    public static BigFraction of(final int num, final int den) {
+        return new BigFraction(BigInteger.valueOf(num), BigInteger.valueOf(den));
+    }
+
+    /**
+     * Create a fraction given the numerator and denominator.
+     * The fraction is reduced to lowest terms.
+     *
+     * @param num the numerator.
+     * @param den the denominator.
+     * @return a new instance.
+     * @throws ArithmeticException if {@code den} is zero.
+     */
+    public static BigFraction of(final long num, final long den) {
+        return new BigFraction(BigInteger.valueOf(num), BigInteger.valueOf(den));
+    }
+
+    /**
+     * Create a fraction given the numerator and denominator.
+     * The fraction is reduced to lowest terms.
+     *
+     * @param num the numerator.
+     * @param den the denominator.
+     * @return a new instance.
      * @throws ArithmeticException if the denominator is zero.
      * @throws NullPointerException if numerator or denominator are null.
      */
-    public static BigFraction of(BigInteger num, BigInteger den) {
+    public static BigFraction of(final BigInteger num, final BigInteger den) {
         return new BigFraction(num, den);
     }
 
+
+    /**
+     * Parses a string that would be produced by {@link #toString()}
+     * and instantiates the corresponding object.
+     *
+     * @param s String representation.
+     * @return an instance.
+     * @throws NumberFormatException if the string does not conform
+     * to the specification.
+     */
+    public static BigFraction parse(String s) {
+        s = s.replace(",", "");
+        final int slashLoc = s.indexOf('/');
+        // if no slash, parse as single number
+        if (slashLoc == -1) {
+            return BigFraction.of(new BigInteger(s.trim()));
+        }
+        final BigInteger num = new BigInteger(
+                s.substring(0, slashLoc).trim());
+        final BigInteger denom = new BigInteger(s.substring(slashLoc + 1).trim());
+        return of(num, denom);
+    }
+
+    @Override
+    public BigFraction zero() {
+        return ZERO;
+    }
+
+    @Override
+    public BigFraction one() {
+        return ONE;
+    }
+
+    /**
+     * Access the numerator as a {@code BigInteger}.
+     *
+     * @return the numerator as a {@code BigInteger}.
+     */
+    public BigInteger getNumerator() {
+        return numerator;
+    }
+
+    /**
+     * Access the numerator as an {@code int}.
+     *
+     * @return the numerator as an {@code int}.
+     */
+    public int getNumeratorAsInt() {
+        return numerator.intValue();
+    }
+
+    /**
+     * Access the numerator as a {@code long}.
+     *
+     * @return the numerator as a {@code long}.
+     */
+    public long getNumeratorAsLong() {
+        return numerator.longValue();
+    }
+
+    /**
+     * Access the denominator as a {@code BigInteger}.
+     *
+     * @return the denominator as a {@code BigInteger}.
+     */
+    public BigInteger getDenominator() {
+        return denominator;
+    }
+
+    /**
+     * Access the denominator as an {@code int}.
+     *
+     * @return the denominator as an {@code int}.
+     */
+    public int getDenominatorAsInt() {
+        return denominator.intValue();
+    }
+
+    /**
+     * Access the denominator as a {@code long}.
+     *
+     * @return the denominator as a {@code long}.
+     */
+    public long getDenominatorAsLong() {
+        return denominator.longValue();
+    }
+
+    /**
+     * Retrieves the sign of this fraction.
+     *
+     * @return -1 if the value is strictly negative, 1 if it is strictly
+     * positive, 0 if it is 0.
+     */
+    public int signum() {
+        final int numS = numerator.signum();
+        final int denS = denominator.signum();
+
+        if ((numS > 0 && denS > 0) ||
+            (numS < 0 && denS < 0)) {
+            return 1;
+        } else if (numS == 0) {
+            return 0;
+        } else {
+            return -1;
+        }
+    }
+
     /**
      * Returns the absolute value of this fraction.
      *
@@ -382,82 +489,72 @@
     }
 
     /**
-     * Adds the value of this fraction to the passed {@link BigInteger},
-     * returning the result in reduced form.
-     *
-     * @param bg
-     *            the {@link BigInteger} to add, must'nt be {@code null}.
-     * @return a {@code BigFraction} instance with the resulting values.
-     */
-    public BigFraction add(final BigInteger bg) {
-        if (numerator.signum() == 0) {
-            return of(bg);
-        }
-        if (bg.signum() == 0) {
-            return this;
-        }
-
-        return new BigFraction(numerator.add(denominator.multiply(bg)), denominator);
-    }
-
-    /**
-     * Adds the value of this fraction to the passed {@code integer}, returning
-     * the result in reduced form.
-     *
-     * @param i
-     *            the {@code integer} to add.
-     * @return a {@code BigFraction} instance with the resulting values.
-     */
-    public BigFraction add(final int i) {
-        return add(BigInteger.valueOf(i));
-    }
-
-    /**
-     * Adds the value of this fraction to the passed {@code long}, returning
-     * the result in reduced form.
-     *
-     * @param l
-     *            the {@code long} to add.
-     * @return a {@code BigFraction} instance with the resulting values.
-     */
-    public BigFraction add(final long l) {
-        return add(BigInteger.valueOf(l));
-    }
-
-    /**
-     * Adds the value of this fraction to another, returning the result in
+     * Return the additive inverse of this fraction, returning the result in
      * reduced form.
      *
-     * @param fraction
-     *            the {@link BigFraction} to add, must not be {@code null}.
-     * @return a {@link BigFraction} instance with the resulting values.
+     * @return the negation of this fraction.
      */
     @Override
-    public BigFraction add(final BigFraction fraction) {
-        if (fraction.numerator.signum() == 0) {
-            return this;
-        }
-        if (numerator.signum() == 0) {
-            return fraction;
-        }
+    public BigFraction negate() {
+        return new BigFraction(numerator.negate(), denominator);
+    }
 
-        final BigInteger num;
-        final BigInteger den;
+    /**
+     * Return the multiplicative inverse of this fraction.
+     *
+     * @return the reciprocal fraction.
+     */
+    @Override
+    public BigFraction reciprocal() {
+        return new BigFraction(denominator, numerator);
+    }
 
-        if (denominator.equals(fraction.denominator)) {
-            num = numerator.add(fraction.numerator);
-            den = denominator;
-        } else {
-            num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator));
-            den = denominator.multiply(fraction.denominator);
-        }
+    /**
+     * Gets the fraction as a {@code double}. This calculates the fraction as
+     * the numerator divided by denominator.
+     *
+     * @return the fraction as a {@code double}
+     * @see java.lang.Number#doubleValue()
+     */
+    @Override
+    public double doubleValue() {
+        return Double.longBitsToDouble(toFloatingPointBits(11, 52));
+    }
 
-        if (num.signum() == 0) {
-            return ZERO;
-        }
+    /**
+     * Retrieves the {@code float} value closest to this fraction.
+     * This calculates the fraction as numerator divided by denominator.
+     *
+     * @return the fraction as a {@code float}.
+     * @see java.lang.Number#floatValue()
+     */
+    @Override
+    public float floatValue() {
+        return Float.intBitsToFloat((int) toFloatingPointBits(8, 23));
+    }
 
-        return new BigFraction(num, den);
+    /**
+     * Gets the fraction as an {@code int}. This returns the whole number part
+     * of the fraction.
+     *
+     * @return the whole number fraction part.
+     * @see java.lang.Number#intValue()
+     */
+    @Override
+    public int intValue() {
+        return numerator.divide(denominator).intValue();
+    }
 
+    /**
+     * Gets the fraction as a {@code long}. This returns the whole number part
+     * of the fraction.
+     *
+     * @return the whole number fraction part.
+     * @see java.lang.Number#longValue()
+     */
+    @Override
+    public long longValue() {
+        return numerator.divide(denominator).longValue();
     }
 
     /**
@@ -506,47 +603,213 @@
     }
 
     /**
-     * Compares this object to another based on size.
+     * Adds the value of this fraction to the passed {@code integer}, returning
+     * the result in reduced form.
      *
-     * @param other Object to compare to, must not be {@code null}.
-     * @return -1 if this is less than {@code object}, +1 if this is greater
-     * than {@code object}, 0 if they are equal.
-     *
-     * @see Comparable#compareTo(Object)
+     * @param i
+     *            the {@code integer} to add.
+     * @return a {@code BigFraction} instance with the resulting values.
      */
-    @Override
-    public int compareTo(final BigFraction other) {
-        final int lhsSigNum = signum();
-        final int rhsSigNum = other.signum();
-
-        if (lhsSigNum != rhsSigNum) {
-            return (lhsSigNum > rhsSigNum) ? 1 : -1;
-        }
-        if (lhsSigNum == 0) {
-            return 0;
-        }
-
-        final BigInteger nOd = numerator.multiply(other.denominator);
-        final BigInteger dOn = denominator.multiply(other.numerator);
-        return nOd.compareTo(dOn);
+    public BigFraction add(final int i) {
+        return add(BigInteger.valueOf(i));
     }
 
     /**
-     * Divide the value of this fraction by the passed {@code BigInteger},
-     * ie {@code this * 1 / bg}, returning the result in reduced form.
+     * Adds the value of this fraction to the passed {@code long}, returning
+     * the result in reduced form.
      *
-     * @param bg the {@code BigInteger} to divide by, must not be {@code null}
-     * @return a {@link BigFraction} instance with the resulting values
-     * @throws ArithmeticException if the value to divide by is zero
+     * @param l
+     *            the {@code long} to add.
+     * @return a {@code BigFraction} instance with the resulting values.
      */
-    public BigFraction divide(final BigInteger bg) {
+    public BigFraction add(final long l) {
+        return add(BigInteger.valueOf(l));
+    }
+
+    /**
+     * Adds the value of this fraction to the passed {@link BigInteger},
+     * returning the result in reduced form.
+     *
+     * @param bg
+     *            the {@link BigInteger} to add, must'nt be {@code null}.
+     * @return a {@code BigFraction} instance with the resulting values.
+     */
+    public BigFraction add(final BigInteger bg) {
+        if (numerator.signum() == 0) {
+            return of(bg);
+        }
         if (bg.signum() == 0) {
-            throw new FractionException(FractionException.ERROR_ZERO_DENOMINATOR);
+            return this;
+        }
+
+        return new BigFraction(numerator.add(denominator.multiply(bg)), denominator);
+    }
+
+    /**
+     * Adds the value of this fraction to another, returning the result in
+     * reduced form.
+     *
+     * @param fraction
+     *            the {@link BigFraction} to add, must not be {@code null}.
+     * @return a {@link BigFraction} instance with the resulting values.
+     */
+    @Override
+    public BigFraction add(final BigFraction fraction) {
+        if (fraction.numerator.signum() == 0) {
+            return this;
         }
         if (numerator.signum() == 0) {
+            return fraction;
+        }
+
+        final BigInteger num;
+        final BigInteger den;
+
+        if (denominator.equals(fraction.denominator)) {
+            num = numerator.add(fraction.numerator);
+            den = denominator;
+        } else {
+            num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator));
+            den = denominator.multiply(fraction.denominator);
+        }
+
+        if (num.signum() == 0) {
             return ZERO;
         }
-        return new BigFraction(numerator, denominator.multiply(bg));
+
+        return new BigFraction(num, den);
+    }
+
+    /**
+     * Subtracts the value of an {@code integer} from the value of this
+     * {@code BigFraction}, returning the result in reduced form.
+     *
+     * @param i the {@code integer} to subtract.
+     * @return a {@code BigFraction} instance with the resulting values.
+     */
+    public BigFraction subtract(final int i) {
+        return subtract(BigInteger.valueOf(i));
+    }
+
+    /**
+     * Subtracts the value of a {@code long} from the value of this
+     * {@code BigFraction}, returning the result in reduced form.
+     *
+     * @param l the {@code long} to subtract.
+     * @return a {@code BigFraction} instance with the resulting values.
+     */
+    public BigFraction subtract(final long l) {
+        return subtract(BigInteger.valueOf(l));
+    }
+
+    /**
+     * Subtracts the value of an {@link BigInteger} from the value of this
+     * {@code BigFraction}, returning the result in reduced form.
+     *
+     * @param bg the {@link BigInteger} to subtract, cannot be {@code null}.
+     * @return a {@code BigFraction} instance with the resulting values.
+     */
+    public BigFraction subtract(final BigInteger bg) {
+        if (bg.signum() == 0) {
+            return this;
+        }
+        if (numerator.signum() == 0) {
+            return of(bg.negate());
+        }
+
+        return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
+    }
+
+    /**
+     * Subtracts the value of another fraction from the value of this one,
+     * returning the result in reduced form.
+     *
+     * @param fraction {@link BigFraction} to subtract, must not be {@code null}.
+     * @return a {@link BigFraction} instance with the resulting values
+     */
+    @Override
+    public BigFraction subtract(final BigFraction fraction) {
+        if (fraction.numerator.signum() == 0) {
+            return this;
+        }
+        if (numerator.signum() == 0) {
+            return fraction.negate();
+        }
+
+        final BigInteger num;
+        final BigInteger den;
+        if (denominator.equals(fraction.denominator)) {
+            num = numerator.subtract(fraction.numerator);
+            den = denominator;
+        } else {
+            num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator));
+            den = denominator.multiply(fraction.denominator);
+        }
+        return new BigFraction(num, den);
+    }
+
+    /**
+     * Multiply the value of this fraction by the passed {@code int}, returning
+     * the result in reduced form.
+     *
+     * @param i
+     *            the {@code int} to multiply by.
+     * @return a {@link BigFraction} instance with the resulting values.
+     */
+    @Override
+    public BigFraction multiply(final int i) {
+        if (i == 0 || numerator.signum() == 0) {
+            return ZERO;
+        }
+
+        return multiply(BigInteger.valueOf(i));
+    }
+
+    /**
+     * Multiply the value of this fraction by the passed {@code long},
+     * returning the result in reduced form.
+     *
+     * @param l
+     *            the {@code long} to multiply by.
+     * @return a {@link BigFraction} instance with the resulting values.
+     */
+    public BigFraction multiply(final long l) {
+        if (l == 0 || numerator.signum() == 0) {
+            return ZERO;
+        }
+
+        return multiply(BigInteger.valueOf(l));
+    }
+
+    /**
+     * Multiplies the value of this fraction by the passed
+     * {@code BigInteger}, returning the result in reduced form.
+     *
+     * @param bg the {@code BigInteger} to multiply by.
+     * @return a {@code BigFraction} instance with the resulting values.
+     */
+    public BigFraction multiply(final BigInteger bg) {
+        if (numerator.signum() == 0 || bg.signum() == 0) {
+            return ZERO;
+        }
+        return new BigFraction(bg.multiply(numerator), denominator);
+    }
+
+    /**
+     * Multiplies the value of this fraction by another, returning the result in
+     * reduced form.
+     *
+     * @param fraction Fraction to multiply by, must not be {@code null}.
+     * @return a {@link BigFraction} instance with the resulting values.
+     */
+    @Override
+    public BigFraction multiply(final BigFraction fraction) {
+        if (numerator.signum() == 0 ||
+            fraction.numerator.signum() == 0) {
+            return ZERO;
+        }
+        return new BigFraction(numerator.multiply(fraction.numerator),
+                               denominator.multiply(fraction.denominator));
     }
 
     /**
@@ -574,6 +837,24 @@
     }
 
     /**
+     * Divide the value of this fraction by the passed {@code BigInteger},
+     * ie {@code this * 1 / bg}, returning the result in reduced form.
+     *
+     * @param bg the {@code BigInteger} to divide by, must not be {@code null}
+     * @return a {@link BigFraction} instance with the resulting values
+     * @throws ArithmeticException if the value to divide by is zero
+     */
+    public BigFraction divide(final BigInteger bg) {
+        if (bg.signum() == 0) {
+            throw new FractionException(FractionException.ERROR_ZERO_DENOMINATOR);
+        }
+        if (numerator.signum() == 0) {
+            return ZERO;
+        }
+        return new BigFraction(numerator, denominator.multiply(bg));
+    }
+
+    /**
      * Divide the value of this fraction by another, returning the result in
      * reduced form.
      *
@@ -594,6 +875,171 @@
     }
 
     /**
+     * Returns a {@code BigFraction} whose value is
+     * {@code (this<sup>exponent</sup>)}, returning the result in reduced form.
+     *
+     * @param exponent
+     *            exponent to which this {@code BigFraction} is to be
+     *            raised.
+     * @return \(\mathit{this}^{\mathit{exponent}}\).
+     */
+    @Override
+    public BigFraction pow(final int exponent) {
+        if (exponent == 0) {
+            return ONE;
+        }
+        if (numerator.signum() == 0) {
+            return this;
+        }
+
+        if (exponent < 0) {
+            return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
+        }
+        return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
+    }
+
+    /**
+     * Returns a {@code BigFraction} whose value is
+     * \(\mathit{this}^{\mathit{exponent}}\), returning the result in reduced form.
+     *
+     * @param exponent
+     *            exponent to which this {@code BigFraction} is to be raised.
+     * @return \(\mathit{this}^{\mathit{exponent}}\) as a {@code BigFraction}.
+     */
+    public BigFraction pow(final long exponent) {
+        if (exponent == 0) {
+            return ONE;
+        }
+        if (numerator.signum() == 0) {
+            return this;
+        }
+
+        if (exponent < 0) {
+            return new BigFraction(ArithmeticUtils.pow(denominator, -exponent),
+                                   ArithmeticUtils.pow(numerator,   -exponent));
+        }
+        return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
+                               ArithmeticUtils.pow(denominator, exponent));
+    }
+
+    /**
+     * Returns a {@code BigFraction} whose value is
+     * \(\mathit{this}^{\mathit{exponent}}\), returning the result in reduced form.
+     *
+     * @param exponent
+     *            exponent to which this {@code BigFraction} is to be raised.
+     * @return \(\mathit{this}^{\mathit{exponent}}\) as a {@code BigFraction}.
+     */
+    public BigFraction pow(final BigInteger exponent) {
+        if (exponent.signum() == 0) {
+            return ONE;
+        }
+        if (numerator.signum() == 0) {
+            return this;
+        }
+
+        if (exponent.signum() == -1) {
+            final BigInteger eNeg = exponent.negate();
+            return new BigFraction(ArithmeticUtils.pow(denominator, eNeg),
+                                   ArithmeticUtils.pow(numerator,   eNeg));
+        }
+        return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
+                               ArithmeticUtils.pow(denominator, exponent));
+    }
+
+    /**
+     * Returns a {@code double} whose value is
+     * \(\mathit{this}^{\mathit{exponent}}\), returning the result in reduced form.
+     *
+     * @param exponent
+     *            exponent to which this {@code BigFraction} is to be raised.
+     * @return \(\mathit{this}^{\mathit{exponent}}\).
+     */
+    public double pow(final double exponent) {
+        return Math.pow(numerator.doubleValue(),   exponent) /
+               Math.pow(denominator.doubleValue(), exponent);
+    }
+
+    /**
+     * Returns the {@code String} representing this fraction.
+     * Uses:
+     * <ul>
+     *  <li>{@code "0"} if {@code numerator} is zero.
+     *  <li>{@code "numerator"} if {@code denominator} is one.
+     *  <li>{@code "numerator / denominator"} for all other cases.
+     * </ul>
+     *
+     * @return a string representation of the fraction.
+     */
+    @Override
+    public String toString() {
+        final String str;
+        if (BigInteger.ONE.equals(denominator)) {
+            str = numerator.toString();
+        } else if (BigInteger.ZERO.equals(numerator)) {
+            str = "0";
+        } else {
+            str = numerator + " / " + denominator;
+        }
+        return str;
+    }
+
+    /**
+     * Compares this object to another based on size.
+     *
+     * @param other Object to compare to, must not be {@code null}.
+     * @return -1 if this is less than {@code object}, +1 if this is greater
+     * than {@code object}, 0 if they are equal.
+     *
+     * @see Comparable#compareTo(Object)
+     */
+    @Override
+    public int compareTo(final BigFraction other) {
+        final int lhsSigNum = signum();
+        final int rhsSigNum = other.signum();
+
+        if (lhsSigNum != rhsSigNum) {
+            return (lhsSigNum > rhsSigNum) ? 1 : -1;
+        }
+        if (lhsSigNum == 0) {
+            return 0;
+        }
+
+        final BigInteger nOd = numerator.multiply(other.denominator);
+        final BigInteger dOn = denominator.multiply(other.numerator);
+        return nOd.compareTo(dOn);
+    }
+
+    /**
+     * Test for the equality of two fractions. If the lowest term numerator and
+     * denominators are the same for both fractions, the two fractions are
+     * considered to be equal.
+     *
+     * @param other {@inheritDoc}
+     * @return {@inheritDoc}
+     */
+    @Override
+    public boolean equals(final Object other) {
+        if (this == other) {
+            return true;
+        } else if (other instanceof BigFraction) {
+            final BigFraction rhs = (BigFraction) other;
+
+            if (signum() == rhs.signum()) {
+                return numerator.abs().equals(rhs.numerator.abs()) &&
+                       denominator.abs().equals(rhs.denominator.abs());
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode();
+    }
+
+    /**
      * Calculates the sign bit, the biased exponent and the significand for a
      * binary floating-point representation of this {@code BigFraction}
      * according to the IEEE 754 standard, and encodes these values into a {@code long}
@@ -757,18 +1203,6 @@
     }
 
     /**
-     * Gets the fraction as a {@code double}. This calculates the fraction as
-     * the numerator divided by denominator.
-     *
-     * @return the fraction as a {@code double}
-     * @see java.lang.Number#doubleValue()
-     */
-    @Override
-    public double doubleValue() {
-        return Double.longBitsToDouble(toFloatingPointBits(11, 52));
-    }
-
-    /**
      * Rounds an integer to the specified power of two (i.e. the minimum number of
      * low-order bits that must be zero) and performs a right-shift by this
      * amount. The rounding mode applied is round to nearest, with ties rounding
@@ -798,445 +1232,4 @@
 
         return result;
     }
-
-    /**
-     * Test for the equality of two fractions. If the lowest term numerator and
-     * denominators are the same for both fractions, the two fractions are
-     * considered to be equal.
-     *
-     * @param other
-     *            fraction to test for equality to this fraction, can be
-     *            {@code null}.
-     * @return true if two fractions are equal, false if object is
-     *         {@code null}, not an instance of {@link BigFraction}, or not
-     *         equal to this fraction instance.
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(final Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof BigFraction) {
-            final BigFraction rhs = (BigFraction) other;
-
-            if (signum() == rhs.signum()) {
-                return numerator.abs().equals(rhs.numerator.abs()) &&
-                    denominator.abs().equals(rhs.denominator.abs());
-            } else {
-                return false;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Retrieves the {@code float} value closest to this fraction.
-     * This calculates the fraction as numerator divided by denominator.
-     *
-     * @return the fraction as a {@code float}.
-     * @see java.lang.Number#floatValue()
-     */
-    @Override
-    public float floatValue() {
-        return Float.intBitsToFloat((int) toFloatingPointBits(8, 23));
-    }
-
-    /**
-     * Access the denominator as a {@code BigInteger}.
-     *
-     * @return the denominator as a {@code BigInteger}.
-     */
-    public BigInteger getDenominator() {
-        return denominator;
-    }
-
-    /**
-     * Access the denominator as an {@code int}.
-     *
-     * @return the denominator as an {@code int}.
-     */
-    public int getDenominatorAsInt() {
-        return denominator.intValue();
-    }
-
-    /**
-     * Access the denominator as a {@code long}.
-     *
-     * @return the denominator as a {@code long}.
-     */
-    public long getDenominatorAsLong() {
-        return denominator.longValue();
-    }
-
-    /**
-     * Access the numerator as a {@code BigInteger}.
-     *
-     * @return the numerator as a {@code BigInteger}.
-     */
-    public BigInteger getNumerator() {
-        return numerator;
-    }
-
-    /**
-     * Access the numerator as an {@code int}.
-     *
-     * @return the numerator as an {@code int}.
-     */
-    public int getNumeratorAsInt() {
-        return numerator.intValue();
-    }
-
-    /**
-     * Access the numerator as a {@code long}.
-     *
-     * @return the numerator as a {@code long}.
-     */
-    public long getNumeratorAsLong() {
-        return numerator.longValue();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode();
-    }
-
-    /**
-     * Gets the fraction as an {@code int}. This returns the whole number part
-     * of the fraction.
-     *
-     * @return the whole number fraction part.
-     * @see java.lang.Number#intValue()
-     */
-    @Override
-    public int intValue() {
-        return numerator.divide(denominator).intValue();
-    }
-
-    /**
-     * Gets the fraction as a {@code long}. This returns the whole number part
-     * of the fraction.
-     *
-     * @return the whole number fraction part.
-     * @see java.lang.Number#longValue()
-     */
-    @Override
-    public long longValue() {
-        return numerator.divide(denominator).longValue();
-    }
-
-    /**
-     * Multiplies the value of this fraction by the passed
-     * {@code BigInteger}, returning the result in reduced form.
-     *
-     * @param bg the {@code BigInteger} to multiply by.
-     * @return a {@code BigFraction} instance with the resulting values.
-     */
-    public BigFraction multiply(final BigInteger bg) {
-        if (numerator.signum() == 0 || bg.signum() == 0) {
-            return ZERO;
-        }
-        return new BigFraction(bg.multiply(numerator), denominator);
-    }
-
-    /**
-     * Multiply the value of this fraction by the passed {@code int}, returning
-     * the result in reduced form.
-     *
-     * @param i
-     *            the {@code int} to multiply by.
-     * @return a {@link BigFraction} instance with the resulting values.
-     */
-    @Override
-    public BigFraction multiply(final int i) {
-        if (i == 0 || numerator.signum() == 0) {
-            return ZERO;
-        }
-
-        return multiply(BigInteger.valueOf(i));
-    }
-
-    /**
-     * Multiply the value of this fraction by the passed {@code long},
-     * returning the result in reduced form.
-     *
-     * @param l
-     *            the {@code long} to multiply by.
-     * @return a {@link BigFraction} instance with the resulting values.
-     */
-    public BigFraction multiply(final long l) {
-        if (l == 0 || numerator.signum() == 0) {
-            return ZERO;
-        }
-
-        return multiply(BigInteger.valueOf(l));
-    }
-
-    /**
-     * Multiplies the value of this fraction by another, returning the result in
-     * reduced form.
-     *
-     * @param fraction Fraction to multiply by, must not be {@code null}.
-     * @return a {@link BigFraction} instance with the resulting values.
-     */
-    @Override
-    public BigFraction multiply(final BigFraction fraction) {
-        if (numerator.signum() == 0 ||
-            fraction.numerator.signum() == 0) {
-            return ZERO;
-        }
-        return new BigFraction(numerator.multiply(fraction.numerator),
-                               denominator.multiply(fraction.denominator));
-    }
-
-    /**
-     * Retrieves the sign of this fraction.
-     *
-     * @return -1 if the value is strictly negative, 1 if it is strictly
-     * positive, 0 if it is 0.
-     */
-    public int signum() {
-        final int numS = numerator.signum();
-        final int denS = denominator.signum();
-
-        if ((numS > 0 && denS > 0) ||
-            (numS < 0 && denS < 0)) {
-            return 1;
-        } else if (numS == 0) {
-            return 0;
-        } else {
-            return -1;
-        }
-    }
-
-    /**
-     * Return the additive inverse of this fraction, returning the result in
-     * reduced form.
-     *
-     * @return the negation of this fraction.
-     */
-    @Override
-    public BigFraction negate() {
-        return new BigFraction(numerator.negate(), denominator);
-    }
-
-    /**
-     * Returns a {@code BigFraction} whose value is
-     * {@code (this<sup>exponent</sup>)}, returning the result in reduced form.
-     *
-     * @param exponent
-     *            exponent to which this {@code BigFraction} is to be
-     *            raised.
-     * @return \(\mathit{this}^{\mathit{exponent}}\).
-     */
-    @Override
-    public BigFraction pow(final int exponent) {
-        if (exponent == 0) {
-            return ONE;
-        }
-        if (numerator.signum() == 0) {
-            return this;
-        }
-
-        if (exponent < 0) {
-            return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
-        }
-        return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
-    }
-
-    /**
-     * Returns a {@code BigFraction} whose value is
-     * \(\mathit{this}^{\mathit{exponent}}\), returning the result in reduced form.
-     *
-     * @param exponent
-     *            exponent to which this {@code BigFraction} is to be raised.
-     * @return \(\mathit{this}^{\mathit{exponent}}\) as a {@code BigFraction}.
-     */
-    public BigFraction pow(final long exponent) {
-        if (exponent == 0) {
-            return ONE;
-        }
-        if (numerator.signum() == 0) {
-            return this;
-        }
-
-        if (exponent < 0) {
-            return new BigFraction(ArithmeticUtils.pow(denominator, -exponent),
-                                   ArithmeticUtils.pow(numerator,   -exponent));
-        }
-        return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
-                               ArithmeticUtils.pow(denominator, exponent));
-    }
-
-    /**
-     * Returns a {@code BigFraction} whose value is
-     * \(\mathit{this}^{\mathit{exponent}}\), returning the result in reduced form.
-     *
-     * @param exponent
-     *            exponent to which this {@code BigFraction} is to be raised.
-     * @return \(\mathit{this}^{\mathit{exponent}}\) as a {@code BigFraction}.
-     */
-    public BigFraction pow(final BigInteger exponent) {
-        if (exponent.signum() == 0) {
-            return ONE;
-        }
-        if (numerator.signum() == 0) {
-            return this;
-        }
-
-        if (exponent.signum() == -1) {
-            final BigInteger eNeg = exponent.negate();
-            return new BigFraction(ArithmeticUtils.pow(denominator, eNeg),
-                                   ArithmeticUtils.pow(numerator,   eNeg));
-        }
-        return new BigFraction(ArithmeticUtils.pow(numerator,   exponent),
-                               ArithmeticUtils.pow(denominator, exponent));
-    }
-
-    /**
-     * Returns a {@code double} whose value is
-     * \(\mathit{this}^{\mathit{exponent}}\), returning the result in reduced form.
-     *
-     * @param exponent
-     *            exponent to which this {@code BigFraction} is to be raised.
-     * @return \(\mathit{this}^{\mathit{exponent}}\).
-     */
-    public double pow(final double exponent) {
-        return Math.pow(numerator.doubleValue(),   exponent) /
-               Math.pow(denominator.doubleValue(), exponent);
-    }
-
-    /**
-     * Return the multiplicative inverse of this fraction.
-     *
-     * @return the reciprocal fraction.
-     */
-    @Override
-    public BigFraction reciprocal() {
-        return new BigFraction(denominator, numerator);
-    }
-
-    /**
-     * Subtracts the value of an {@link BigInteger} from the value of this
-     * {@code BigFraction}, returning the result in reduced form.
-     *
-     * @param bg the {@link BigInteger} to subtract, cannot be {@code null}.
-     * @return a {@code BigFraction} instance with the resulting values.
-     */
-    public BigFraction subtract(final BigInteger bg) {
-        if (bg.signum() == 0) {
-            return this;
-        }
-        if (numerator.signum() == 0) {
-            return of(bg.negate());
-        }
-
-        return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
-    }
-
-    /**
-     * Subtracts the value of an {@code integer} from the value of this
-     * {@code BigFraction}, returning the result in reduced form.
-     *
-     * @param i the {@code integer} to subtract.
-     * @return a {@code BigFraction} instance with the resulting values.
-     */
-    public BigFraction subtract(final int i) {
-        return subtract(BigInteger.valueOf(i));
-    }
-
-    /**
-     * Subtracts the value of a {@code long} from the value of this
-     * {@code BigFraction}, returning the result in reduced form.
-     *
-     * @param l the {@code long} to subtract.
-     * @return a {@code BigFraction} instance with the resulting values.
-     */
-    public BigFraction subtract(final long l) {
-        return subtract(BigInteger.valueOf(l));
-    }
-
-    /**
-     * Subtracts the value of another fraction from the value of this one,
-     * returning the result in reduced form.
-     *
-     * @param fraction {@link BigFraction} to subtract, must not be {@code null}.
-     * @return a {@link BigFraction} instance with the resulting values
-     */
-    @Override
-    public BigFraction subtract(final BigFraction fraction) {
-        if (fraction.numerator.signum() == 0) {
-            return this;
-        }
-        if (numerator.signum() == 0) {
-            return fraction.negate();
-        }
-
-        final BigInteger num;
-        final BigInteger den;
-        if (denominator.equals(fraction.denominator)) {
-            num = numerator.subtract(fraction.numerator);
-            den = denominator;
-        } else {
-            num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator));
-            den = denominator.multiply(fraction.denominator);
-        }
-        return new BigFraction(num, den);
-    }
-
-    /**
-     * Returns the {@code String} representing this fraction, ie
-     * "num / dem" or just "num" if the denominator is one.
-     *
-     * @return a string representation of the fraction.
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        final String str;
-        if (BigInteger.ONE.equals(denominator)) {
-            str = numerator.toString();
-        } else if (BigInteger.ZERO.equals(numerator)) {
-            str = "0";
-        } else {
-            str = numerator + " / " + denominator;
-        }
-        return str;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BigFraction zero() {
-        return ZERO;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public BigFraction one() {
-        return ONE;
-    }
-
-    /**
-     * Parses a string that would be produced by {@link #toString()}
-     * and instantiates the corresponding object.
-     *
-     * @param s String representation.
-     * @return an instance.
-     * @throws NumberFormatException if the string does not conform
-     * to the specification.
-     */
-    public static BigFraction parse(String s) {
-        s = s.replace(",", "");
-        final int slashLoc = s.indexOf('/');
-        // if no slash, parse as single number
-        if (slashLoc == -1) {
-            return BigFraction.of(new BigInteger(s.trim()));
-        } else {
-            final BigInteger num = new BigInteger(
-                    s.substring(0, slashLoc).trim());
-            final BigInteger denom = new BigInteger(s.substring(slashLoc + 1).trim());
-            return of(num, denom);
-        }
-    }
 }
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index 00dd80e..8135438 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -35,23 +35,61 @@
     implements Comparable<Fraction>,
                NativeOperators<Fraction>,
                Serializable {
-    /** A fraction representing "1". */
-    public static final Fraction ONE = new Fraction(1, 1);
-
     /** A fraction representing "0". */
     public static final Fraction ZERO = new Fraction(0, 1);
 
+    /** A fraction representing "1". */
+    public static final Fraction ONE = new Fraction(1, 1);
+
     /** Serializable version identifier. */
     private static final long serialVersionUID = 20190701L;
 
     /** The default epsilon used for convergence. */
     private static final double DEFAULT_EPSILON = 1e-5;
 
+    /** The numerator of this fraction reduced to lowest terms. */
+    private final int numerator;
+
     /** The denominator of this fraction reduced to lowest terms. */
     private final int denominator;
 
-    /** The numerator of this fraction reduced to lowest terms. */
-    private final int numerator;
+
+    /**
+     * Constructs an instance.
+     *
+     * @param num Numerator.
+     * @param den Denominator.
+     * @throws ArithmeticException if the denominator is {@code zero}
+     * or if integer overflow occurs.
+     */
+    private Fraction(int num, int den) {
+        if (den == 0) {
+            throw new ArithmeticException("division by zero");
+        }
+
+        if (num == den) {
+            numerator = 1;
+            denominator = 1;
+        } else {
+            // If num and den are both 2^-31, or if one is 0 and the other is 2^-31,
+            // the calculation of the gcd below will fail. Ensure that this does not
+            // happen by dividing both by 2 in case both are even.
+            if (((num | den) & 1) == 0) {
+                num >>= 1;
+                den >>= 1;
+            }
+
+            // Reduce numerator and denominator by greatest common divisor.
+            final int d = ArithmeticUtils.gcd(num, den);
+            if (d > 1) {
+                num /= d;
+                den /= d;
+            }
+
+            numerator = num;
+            denominator = den;
+        }
+    }
 
     /**
      * Create a fraction given the double value and either the maximum error
@@ -85,7 +123,10 @@
      * @throws ArithmeticException if the continued fraction failed
      * to converge.
      */
-    private Fraction(double value, double epsilon, int maxDenominator, int maxIterations) {
+    private Fraction(final double value,
+                     final double epsilon,
+                     final int maxDenominator,
+                     final int maxIterations) {
         final long overflow = Integer.MAX_VALUE;
         double r0 = value;
         long a0 = (long)Math.floor(r0);
@@ -157,43 +198,6 @@
     }
 
     /**
-     * Constructs an instance.
-     *
-     * @param num Numerator.
-     * @param den Denominator.
-     * @throws ArithmeticException if the denominator is {@code zero}
-     * or if integer overflow occurs.
-     */
-    private Fraction(int num, int den) {
-        if (den == 0) {
-            throw new ArithmeticException("division by zero");
-        }
-
-        if (num == den) {
-            numerator = 1;
-            denominator = 1;
-        } else {
-            // If num and den are both 2^-31, or if one is 0 and the other is 2^-31,
-            // the calculation of the gcd below will fail. Ensure that this does not
-            // happen by dividing both by 2 in case both are even.
-            if (((num | den) & 1) == 0) {
-                num >>= 1;
-                den >>= 1;
-            }
-
-            // Reduce numerator and denominator by greatest common divisor.
-            final int d = ArithmeticUtils.gcd(num, den);
-            if (d > 1) {
-                num /= d;
-                den /= d;
-            }
-
-            numerator = num;
-            denominator = den;
-        }
-    }
-
-    /**
      * Create a fraction given the double value.
      *
      * @param value Value to convert to a fraction.
@@ -201,7 +205,7 @@
      * converge.
      * @return a new instance.
      */
-    public static Fraction from(double value) {
+    public static Fraction from(final double value) {
         return from(value, DEFAULT_EPSILON, 100);
     }
 
@@ -223,7 +227,9 @@
      * converge.
      * @return a new instance.
      */
-    public static Fraction from(double value, double epsilon, int maxIterations) {
+    public static Fraction from(final double value,
+                                final double epsilon,
+                                final int maxIterations) {
         return new Fraction(value, epsilon, Integer.MAX_VALUE, maxIterations);
     }
 
@@ -243,7 +249,8 @@
      * converge.
      * @return a new instance.
      */
-    public static Fraction from(double value, int maxDenominator) {
+    public static Fraction from(final double value,
+                                final int maxDenominator) {
         return new Fraction(value, 0, maxDenominator, 100);
     }
 
@@ -253,7 +260,7 @@
      * @param num Numerator.
      * @return a new instance.
      */
-    public static Fraction of(int num) {
+    public static Fraction of(final int num) {
         return of(num, 1);
     }
 
@@ -267,90 +274,39 @@
      * or if integer overflow occurs.
      * @return a new instance.
      */
-    public static Fraction of(int num, int den) {
+    public static Fraction of(final int num, final int den) {
         return new Fraction(num, den);
     }
 
     /**
-     * Returns the absolute value of this fraction.
+     * Parses a string that would be produced by {@link #toString()}
+     * and instantiates the corresponding object.
      *
-     * @return the absolute value.
+     * @param s String representation.
+     * @return an instance.
+     * @throws NumberFormatException if the string does not conform to the
+     * specification.
      */
-    public Fraction abs() {
-        return signum() >= 0 ?
-            this :
-            negate();
-    }
-
-    /**
-     * Compares this object to another based on size.
-     *
-     * @param other Object to compare to.
-     * @return -1 if this is less than {@code object}, +1 if this is greater
-     * than {@code object}, 0 if they are equal.
-     */
-    @Override
-    public int compareTo(Fraction other) {
-        return Long.compare(((long) numerator) * other.denominator,
-                            ((long) denominator) * other.numerator);
-    }
-
-    /**
-     * Retrieves the {@code double} value closest to this fraction.
-     * This calculates the fraction as numerator divided by denominator.
-     *
-     * @return the fraction as a {@code double}.
-     */
-    @Override
-    public double doubleValue() {
-        return (double) numerator / (double) denominator;
-    }
-
-    /**
-     * Test for the equality of two fractions.
-     * If the lowest term numerator and denominators are the same for
-     * both fractions, the two fractions are considered to be equal.
-     * @param other Fraction to test for equality with.
-     * @return {@code true} if the two fractions are equal, {@code false}
-     * otherwise.
-     */
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
+    public static Fraction parse(String s) {
+        final int slashLoc = s.indexOf('/');
+        // if no slash, parse as single number
+        if (slashLoc == -1) {
+            return Fraction.of(Integer.parseInt(s.trim()));
+        } else {
+            final int num = Integer.parseInt(s.substring(0, slashLoc).trim());
+            final int denom = Integer.parseInt(s.substring(slashLoc + 1).trim());
+            return of(num, denom);
         }
-
-        if (other instanceof Fraction) {
-            // Since fractions are always in lowest terms, numerators and
-            // denominators can be compared directly for equality.
-            final Fraction rhs = (Fraction) other;
-            if (signum() == rhs.signum()) {
-                return Math.abs(numerator) == Math.abs(rhs.numerator) &&
-                    Math.abs(denominator) == Math.abs(rhs.denominator);
-            } else {
-                return false;
-            }
-        }
-
-        return false;
     }
 
-    /**
-     * Retrieves the {@code float} value closest to this fraction.
-     * This calculates the fraction as numerator divided by denominator.
-     *
-     * @return the fraction as {@code float}.
-     */
     @Override
-    public float floatValue() {
-        return (float) doubleValue();
+    public Fraction zero() {
+        return ZERO;
     }
 
-    /**
-     * @return the denominator.
-     */
-    public int getDenominator() {
-        return denominator;
+    @Override
+    public Fraction one() {
+        return ONE;
     }
 
     /**
@@ -360,32 +316,11 @@
         return numerator;
     }
 
-    /** {@inheritDoc} */
-    @Override
-    public int hashCode() {
-        return 37 * (37 * 17 + numerator) + denominator;
-    }
-
     /**
-     * Retrieves the whole number part of the fraction.
-     *
-     * @return the largest {@code int} value that is not larger than
-     * this fraction.
+     * @return the denominator.
      */
-    @Override
-    public int intValue() {
-        return (int) doubleValue();
-    }
-
-    /**
-     * Retrieves the whole number part of the fraction.
-     *
-     * @return the largest {@code long} value that is not larger than
-     * this fraction.
-     */
-    @Override
-    public long longValue() {
-        return (long) doubleValue();
+    public int getDenominator() {
+        return denominator;
     }
 
     /**
@@ -406,6 +341,17 @@
     }
 
     /**
+     * Returns the absolute value of this fraction.
+     *
+     * @return the absolute value.
+     */
+    public Fraction abs() {
+        return signum() >= 0 ?
+            this :
+            negate();
+    }
+
+    /**
      * Computes the additive inverse of this fraction.
      *
      * @return the opposite.
@@ -428,6 +374,60 @@
     }
 
     /**
+     * Retrieves the {@code double} value closest to this fraction.
+     * This calculates the fraction as numerator divided by denominator.
+     *
+     * @return the fraction as a {@code double}.
+     */
+    @Override
+    public double doubleValue() {
+        return (double) numerator / (double) denominator;
+    }
+
+    /**
+     * Retrieves the {@code float} value closest to this fraction.
+     * This calculates the fraction as numerator divided by denominator.
+     *
+     * @return the fraction as {@code float}.
+     */
+    @Override
+    public float floatValue() {
+        return (float) doubleValue();
+    }
+
+    /**
+     * Retrieves the whole number part of the fraction.
+     *
+     * @return the largest {@code int} value that is not larger than
+     * this fraction.
+     */
+    @Override
+    public int intValue() {
+        return (int) doubleValue();
+    }
+
+    /**
+     * Retrieves the whole number part of the fraction.
+     *
+     * @return the largest {@code long} value that is not larger than
+     * this fraction.
+     */
+    @Override
+    public long longValue() {
+        return (long) doubleValue();
+    }
+
+    /**
+     * Adds an integer to the fraction.
+     *
+     * @param i Value to add.
+     * @return {@code this + i}.
+     */
+    public Fraction add(final int i) {
+        return new Fraction(numerator + i * denominator, denominator);
+    }
+
+    /**
      * Adds the value of this fraction to another, returning the result
      * in reduced form.
      * The algorithm follows Knuth, 4.5.1.
@@ -443,13 +443,13 @@
     }
 
     /**
-     * Adds an integer to the fraction.
+     * Subtracts an integer from this fraction.
      *
-     * @param i Value to add.
-     * @return {@code this + i}.
+     * @param i Value to subtract.
+     * @return {@code this - i}.
      */
-    public Fraction add(final int i) {
-        return new Fraction(numerator + i * denominator, denominator);
+    public Fraction subtract(final int i) {
+        return new Fraction(numerator - i * denominator, denominator);
     }
 
     /**
@@ -467,16 +467,6 @@
     }
 
     /**
-     * Subtracts an integer from this fraction.
-     *
-     * @param i Value to subtract.
-     * @return {@code this - i}.
-     */
-    public Fraction subtract(final int i) {
-        return new Fraction(numerator - i * denominator, denominator);
-    }
-
-    /**
      * Implements add and subtract using algorithm described in Knuth 4.5.1.
      *
      * @param fraction Fraction to add or subtract.
@@ -529,6 +519,17 @@
     }
 
     /**
+     * Multiplies the fraction by an integer.
+     *
+     * @param i Value to multiply by.
+     * @return {@code this * i}.
+     */
+    @Override
+    public Fraction multiply(final int i) {
+        return multiply(of(i));
+    }
+
+    /**
      * Multiplies the value of this fraction by another, returning the
      * result in reduced form.
      *
@@ -553,14 +554,13 @@
     }
 
     /**
-     * Multiplies the fraction by an integer.
+     * Divides the fraction by an integer.
      *
-     * @param i Value to multiply by.
+     * @param i Value to divide by.
      * @return {@code this * i}.
      */
-    @Override
-    public Fraction multiply(final int i) {
-        return multiply(of(i));
+    public Fraction divide(final int i) {
+        return divide(of(i));
     }
 
     /**
@@ -583,36 +583,38 @@
     }
 
     /**
-     * Divides the fraction by an integer.
+     * {@inheritDoc}
      *
-     * @param i Value to divide by.
-     * @return {@code this * i}.
-     */
-    public Fraction divide(final int i) {
-        return divide(of(i));
-    }
-
-    /**
-     * @param n Power.
-     * @return <code>this<sup>n</sup></code>.
+     * @param exponent {@inheritDoc}
+     * @return <code>this<sup>exponent</sup></code>.
      */
     @Override
-    public Fraction pow(final int n) {
-        if (n == 0) {
+    public Fraction pow(final int exponent) {
+        if (exponent == 0) {
             return ONE;
         }
         if (numerator == 0) {
             return this;
         }
 
-        return n < 0 ?
-            new Fraction(ArithmeticUtils.pow(denominator, -n),
-                         ArithmeticUtils.pow(numerator, -n)) :
-            new Fraction(ArithmeticUtils.pow(numerator, n),
-                         ArithmeticUtils.pow(denominator, n));
+        return exponent < 0 ?
+            new Fraction(ArithmeticUtils.pow(denominator, -exponent),
+                         ArithmeticUtils.pow(numerator, -exponent)) :
+            new Fraction(ArithmeticUtils.pow(numerator, exponent),
+                         ArithmeticUtils.pow(denominator, exponent));
     }
 
-    /** {@inheritDoc} */
+    /**
+     * Returns the {@code String} representing this fraction.
+     * Uses:
+     * <ul>
+     *  <li>{@code "0"} if {@code numerator} is zero.
+     *  <li>{@code "numerator"} if {@code denominator} is one.
+     *  <li>{@code "numerator / denominator"} for all other cases.
+     * </ul>
+     *
+     * @return a string representation of the fraction.
+     */
     @Override
     public String toString() {
         final String str;
@@ -626,36 +628,46 @@
         return str;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * Compares this object with the specified object for order using the signed magnitude.
+     *
+     * @param other {@inheritDoc}
+     * @return {@inheritDoc}
+     */
     @Override
-    public Fraction zero() {
-        return ZERO;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Fraction one() {
-        return ONE;
+    public int compareTo(Fraction other) {
+        return Long.compare(((long) numerator) * other.denominator,
+                            ((long) denominator) * other.numerator);
     }
 
     /**
-     * Parses a string that would be produced by {@link #toString()}
-     * and instantiates the corresponding object.
+     * Test for equality with another object. If the other object is a {@code Fraction} then a
+     * comparison is made of the sign and magnitude; otherwise {@code false} is returned.
      *
-     * @param s String representation.
-     * @return an instance.
-     * @throws NumberFormatException if the string does not conform to the
-     * specification.
+     * @param other {@inheritDoc}
+     * @return {@inheritDoc}
      */
-    public static Fraction parse(String s) {
-        final int slashLoc = s.indexOf('/');
-        // if no slash, parse as single number
-        if (slashLoc == -1) {
-            return Fraction.of(Integer.parseInt(s.trim()));
-        } else {
-            final int num = Integer.parseInt(s.substring(0, slashLoc).trim());
-            final int denom = Integer.parseInt(s.substring(slashLoc + 1).trim());
-            return of(num, denom);
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
         }
+
+        if (other instanceof Fraction) {
+            // Since fractions are always in lowest terms, numerators and
+            // denominators can be compared directly for equality.
+            final Fraction rhs = (Fraction) other;
+            if (signum() == rhs.signum()) {
+                return Math.abs(numerator) == Math.abs(rhs.numerator) &&
+                    Math.abs(denominator) == Math.abs(rhs.denominator);
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return 37 * (37 * 17 + numerator) + denominator;
     }
 }
