diff --git a/src/java/org/apache/commons/lang/math/Fraction.java b/src/java/org/apache/commons/lang/math/Fraction.java new file mode 100644 index 000000000..5d489ca50 --- /dev/null +++ b/src/java/org/apache/commons/lang/math/Fraction.java @@ -0,0 +1,735 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import java.io.Serializable; + +/** + *

Fraction is a Number implementation that + * stores fractions accurately.

+ * + *

This class is immutable, and interoperable with most methods that accept + * a Number.

+ * + * @author Travis Reeder + * @author Stephen Colebourne + * @since 2.0 + * @version $Id: Fraction.java,v 1.1 2002/12/22 19:39:39 scolebourne Exp $ + */ +public final class Fraction extends Number implements Serializable, Comparable { + + private static final long serialVersionUID = 65382027393090L; + + public static final Fraction ZERO = new Fraction(0, 1); + public static final Fraction ONE = new Fraction(1, 1); + + public static final Fraction ONE_HALF = new Fraction(1, 2); + + public static final Fraction ONE_THIRD = new Fraction(1, 3); + public static final Fraction TWO_THIRDS = new Fraction(2, 3); + + public static final Fraction ONE_QUARTER = new Fraction(1, 4); + public static final Fraction TWO_QUARTERS = new Fraction(2, 4); + public static final Fraction THREE_QUARTERS = new Fraction(3, 4); + + public static final Fraction ONE_FIFTH = new Fraction(1, 5); + public static final Fraction TWO_FIFTHS = new Fraction(2, 5); + public static final Fraction THREE_FIFTHS = new Fraction(3, 5); + public static final Fraction FOUR_FIFTHS = new Fraction(4, 5); + + + /** The numerator number part of the fraction (the three in three sevenths) */ + private final int numerator; + /** The denominator number part of the fraction (the seven in three sevenths) */ + private final int denominator; + + /** Cached output hashCode (class is immutable) */ + private transient int hashCode = 0; + /** Cached output toString (class is immutable) */ + private transient String toString = null; + /** Cached output toProperString (class is immutable) */ + private transient String toProperString = null; + + /** + *

Constructs a Fraction instance with the 2 parts + * of a fraction Y/Z.

+ * + * @param numerator the numerator, for example the three in 'three sevenths' + * @param denominator the denominator, for example the seven in 'three sevenths' + */ + private Fraction(int numerator, int denominator) { + super(); + this.numerator = numerator; + this.denominator = denominator; + } + + /** + *

Creates a Fraction instance with the 2 parts + * of a fraction Y/Z.

+ * + *

Any negative signs are resolved to be on the numerator.

+ * + * @param numerator the numerator, for example the three in 'three sevenths' + * @param denominator the denominator, for example the seven in 'three sevenths' + * @return a new fraction instance + * @throws ArithmeticException if the denomiator is zero + */ + public static Fraction getFraction(int numerator, int denominator) { + if (denominator == 0) { + throw new ArithmeticException("The denominator must not be zero"); + } + if (denominator < 0) { + numerator = -numerator; + denominator = -denominator; + } + return new Fraction(numerator, denominator); + } + + /** + *

Creates a Fraction instance with the 3 parts + * of a fraction X Y/Z.

+ * + *

The negative sign must be passed in on the whole number part.

+ * + * @param whole the whole number, for example the one in 'one and three sevenths' + * @param numerator the numerator, for example the three in 'one and three sevenths' + * @param denominator the denominator, for example the seven in 'one and three sevenths' + * @return a new fraction instance + * @throws ArithmeticException if the denomiator is zero + * @throws ArithmeticException if the denomiator is negative + * @throws ArithmeticException if the numerator is negative + */ + public static Fraction getFraction(int whole, int numerator, int denominator) { + if (denominator == 0) { + throw new ArithmeticException("The denominator must not be zero"); + } + if (denominator < 0) { + throw new ArithmeticException("The denominator must not be negative"); + } + if (numerator < 0) { + throw new ArithmeticException("The numerator must not be negative"); + } + if (whole < 0) { + numerator = whole * denominator - numerator; + } else { + numerator = whole * denominator + numerator; + } + return new Fraction(numerator, denominator); + } + + /** + *

Creates a Fraction instance with the 2 parts + * of a fraction Y/Z.

+ * + *

Any negative signs are resolved to be on the numerator.

+ * + * @param numerator the numerator, for example the three in 'three sevenths' + * @param denominator the denominator, for example the seven in 'three sevenths' + * @return a new fraction instance, with the numerator and denominator reduced + * @throws ArithmeticException if the denomiator is zero + */ + public static Fraction getReducedFraction(int numerator, int denominator) { + if (denominator == 0) { + throw new ArithmeticException("The denominator must not be zero"); + } + if (denominator < 0) { + numerator = -numerator; + denominator = -denominator; + } + int gcd = greatestCommonDenominator(Math.abs(numerator), denominator); + if (gcd == 0) { + return new Fraction(numerator, denominator); + } + return new Fraction(numerator / gcd, denominator / gcd); + } + + /** + *

Creates a Fraction instance from a double value.

+ * + *

This method uses the continued fraction algorithm.

+ * + * @param value the double value to convert + * @return a new fraction instance that is close to the value + * @throws ArithmeticException if the value is infinite or NaN + * @throws ArithmeticException if the calculated denomiator is zero + */ + public static Fraction getFraction(double value) { + if (Double.isInfinite(value) || Double.isNaN(value)) { + throw new ArithmeticException("The value must not be infinite or NaN"); + } + int sign = (value < 0 ? -1 : 1); + value = Math.abs(value); + int wholeNumber = (int) value; + value -= wholeNumber; + + // http://archives.math.utk.edu/articles/atuyl/confrac/ + int numer0 = 0; // the pre-previous + int denom0 = 1; // the pre-previous + int numer1 = 1; // the previous + int denom1 = 0; // the previous + int numer2 = 0; // the current, setup in calculation + int denom2 = 0; // the current, setup in calculation + int a1 = (int) value; + int a2 = 0; + double x1 = 1; + double x2 = 0; + double y1 = value - a1; + double y2 = 0; + double delta1, delta2 = Double.MAX_VALUE; + double fraction; + int i = 1; +// System.out.println("---"); + do { + delta1 = delta2; + a2 = (int) (x1 / y1); + x2 = y1; + y2 = x1 - a2 * y1; + numer2 = a1 * numer1 + numer0; + denom2 = a1 * denom1 + denom0; + fraction = (double) numer2 / (double) denom2; + delta2 = Math.abs(value - fraction); +// System.out.println(numer2 + " " + denom2 + " " + fraction + " " + delta2 + " " + y1); + a1 = a2; + x1 = x2; + y1 = y2; + numer0 = numer1; + denom0 = denom1; + numer1 = numer2; + denom1 = denom2; + i++; +// System.out.println(">>" + delta1 +" "+ delta2+" "+(delta1 > delta2)+" "+i+" "+denom2); + } while ((delta1 > delta2) && (denom2 <= 10000) && (denom2 > 0) && (i < 25)); + if (i == 25) { + throw new ArithmeticException("Unable to convert double to fraction"); + } + return getReducedFraction((numer0 + wholeNumber * denom0) * sign, denom0); + } + + /** + *

Creates a Fraction from a String.

+ * + *

The formats accepted are:

+ *
    + *
  1. double String containing a dot + *
  2. 'X Y/Z' + *
  3. 'Y/Z' + *
and a .

+ * + * @param str the string to parse, must not be null + * @return the new Fraction instance + * @throws IllegalArgumentException if the string is null + * @throws NumberFormatException if the number format is invalid + */ + public static Fraction getFraction(String str) { + if (str == null) { + throw new IllegalArgumentException("The string must not be null"); + } + // parse double format + int pos = str.indexOf('.'); + if (pos >= 0) { + return getFraction(Double.parseDouble(str)); + } + + // parse X Y/Z format + pos = str.indexOf(' '); + if (pos > 0) { + int whole = Integer.parseInt(str.substring(0, pos)); + str = str.substring(pos + 1); + pos = str.indexOf('/'); + if (pos < 0) { + throw new NumberFormatException("The fraction could not be parsed as the format X Y/Z"); + } else { + int denom = Integer.parseInt(str.substring(pos + 1)); + return getFraction( + Integer.parseInt(str.substring(0, pos)) + whole * denom, + denom + ); + } + } + + // parse Y/Z format + pos = str.indexOf('/'); + if (pos < 0) { + // simple whole number + return getFraction(Integer.parseInt(str), 1); + } else { + return getFraction( + Integer.parseInt(str.substring(0, pos)), + Integer.parseInt(str.substring(pos + 1)) + ); + } + } + + // Accessors + //------------------------------------------------------------------- + + /** + *

Gets the numerator part of the fraction.

+ * + *

This method may return a value greater than the denominator, an + * improper fraction, such as the seven in 7/8.

+ * + * @return the numerator fraction part + */ + public int getNumerator() { + return numerator; + } + + /** + *

Gets the denominator part of the fraction.

+ * + * @return the denominator fraction part + */ + public int getDenominator() { + return denominator; + } + + /** + *

Gets the proper numerator, always positive.

+ * + *

An improper fraction 7/8 can be resolved into a proper one, 1 3/4. + * This method returns the 3 from the proper fraction.

+ * + *

If the fraction is negative such as -7/8, it can be resolved into + * -1 3/4, so this method returns the positive proper numerator, 3.

+ * + * @return the numerator fraction part of a proper fraction, always positive + */ + public int getProperNumerator() { + return Math.abs(numerator % denominator); + } + + /** + *

Gets the proper whole part of the fraction.

+ * + *

An improper fraction 7/8 can be resolved into a proper one, 1 3/4. + * This method returns the 1 from the proper fraction.

+ * + *

If the fraction is negative such as -7/8, it can be resolved into + * -1 3/4, so this method returns the positive whole part -1.

+ * + * @return the whole fraction part of a proper fraction, that includes the sign + */ + public int getProperWhole() { + return numerator / denominator; + } + + // Number methods + //------------------------------------------------------------------- + + /** + *

Gets the fraction as an int. This returns the whole number + * part of the fraction.

+ * + * @return the whole number fraction part + */ + public int intValue() { + return (int) numerator / denominator; + } + + /** + *

Gets the fraction as a long. This returns the whole number + * part of the fraction.

+ * + * @return the whole number fraction part + */ + public long longValue() { + return (long) numerator / denominator; + } + + /** + *

Gets the fraction as a float. This calculates the fraction + * as the numerator divided by denominator.

+ * + * @return the fraction as a float + */ + public float floatValue() { + return ((float) numerator) / ((float) denominator); + } + + /** + *

Gets the fraction as a double. This calculates the fraction + * as the numerator divided by denominator.

+ * + * @return the fraction as a double + */ + public double doubleValue() { + return ((double) numerator) / ((double) denominator); + } + + // Calculations + //------------------------------------------------------------------- + + /** + *

Reduce the fraction to the smallest values for the numerator and + * denominator, returning the result..

+ * + * @return a new reduce fraction instance, or this if no simplification possible + */ + public Fraction reduce() { + int gcd = greatestCommonDenominator(Math.abs(numerator), denominator); + if (gcd == 0) { + return this; + } + return Fraction.getFraction(numerator / gcd, denominator / gcd); + } + + /** + *

Gets a fraction that is the invert (1/fraction) of this one.

+ * + *

The returned fraction is not reduced.

+ * + * @return a new fraction instance with the numerator and denominator inverted + * @throws ArithmeticException if the numerator is zero + */ + public Fraction invert() { + if (numerator == 0) { + throw new ArithmeticException("Unable to invert a fraction with a zero numerator"); + } + return getFraction(denominator, numerator); + } + + /** + *

Gets a fraction that is the negative (-fraction) of this one.

+ * + *

The returned fraction is not reduced.

+ * + * @return a new fraction instance with the opposite signed numerator + */ + public Fraction negate() { + return getFraction(-numerator, denominator); + } + + /** + *

Gets a fraction that is the positive equivalent + * (fraction >= 0 ? this : -fraction) of this one.

+ * + *

The returned fraction is not reduced.

+ * + * @return this if it is positive, or a new positive fraction + * instance with the opposite signed numerator + */ + public Fraction abs() { + if (numerator >= 0) { + return this; + } + return getFraction(-numerator, denominator); + } + + /** + *

Gets a fraction that is raised to the passed in power.

+ * + *

The returned fraction is not reduced.

+ * + * @param power the power to raise the fraction to + * @return this if the power is one, ONE if the power + * is zero or a new fraction instance raised to the appropriate power + */ + public Fraction pow(int power) { + if (power == 1) { + return this; + } else if (power == 0) { + return ONE; + } else if (power < 0) { + return getFraction((int) Math.pow(denominator, -power), (int) Math.pow(numerator, -power)); + } + return getFraction((int) Math.pow(numerator, power), (int) Math.pow(denominator, power)); + } + + /** + *

Gets the greatest common denominator of two numbers.

+ * + * @param number1 a positive number + * @param number2 a positive number + * @return the greatest common denominator + */ + private static int greatestCommonDenominator(int number1, int number2) { + int remainder = number1 % number2; + while (remainder != 0) { + number1 = number2; + number2 = remainder; + remainder = number1 % number2; + } + return number2; + } + + // Arithmetic + //------------------------------------------------------------------- + + /** + *

Adds the value of this fraction to another, returning the result.

+ * + *

The implementation spots common cases of zero numerators and equal + * denominators. Otherwise, it uses (a/b) + (c/d) = (a*d + b*c) / (b*d) + * and then reduces the result.

+ * + * @param the fraction to add, must not be null + * @return a Fraction instance with the resulting values + * @throws IllegalArgumentException if the fraction is null + */ + public Fraction add(Fraction fraction) { + if (fraction == null) { + throw new IllegalArgumentException("The fraction must not be null"); + } + if (numerator == 0) { + return fraction; + } + if (fraction.numerator == 0) { + return this; + } + if (denominator == fraction.denominator) { + return getReducedFraction(numerator + fraction.numerator, denominator); + } + return getReducedFraction( + numerator * fraction.denominator + denominator * fraction.numerator, + denominator * fraction.denominator + ); + } + + /** + *

Subtracts the value of another fraction from the value of this one, + * returning the result.

+ * + *

The implementation spots common cases of zero numerators and equal + * denominators. Otherwise, it uses (a/b) - (c/d) = (a*d - b*c) / (b*d) + * and then reduces the result.

+ * + * @param the fraction to subtract, must not be null + * @return a Fraction instance with the resulting values + * @throws IllegalArgumentException if the fraction is null + */ + public Fraction subtract(Fraction fraction) { + if (fraction == null) { + throw new IllegalArgumentException("The fraction must not be null"); + } + if (numerator == 0) { + return fraction.negate(); + } + if (fraction.numerator == 0) { + return this; + } + if (denominator == fraction.denominator) { + return getReducedFraction(numerator - fraction.numerator, denominator); + } + return getReducedFraction( + numerator * fraction.denominator - denominator * fraction.numerator, + denominator * fraction.denominator + ); + } + + /** + *

Multiplies the value of this fraction by another, returning the result.

+ * + *

The implementation uses (a/b)*(c/d) = (a*c)/(b*d) + * and then reduces the result.

+ * + * @param the fraction to multipy by, must not be null + * @return a Fraction instance with the resulting values + * @throws IllegalArgumentException if the fraction is null + */ + public Fraction multiplyBy(Fraction fraction) { + if (fraction == null) { + throw new IllegalArgumentException("The fraction must not be null"); + } + if (numerator == 0 || fraction.numerator == 0) { + return ZERO; + } + return getReducedFraction( + numerator * fraction.numerator, + denominator * fraction.denominator + ); + } + + /** + *

Divide the value of this fraction by another, returning the result.

+ * + *

The implementation uses (a/b)/(c/d) = a/b * d/c = (a*d)/(b*c) + * and then reduces the result.

+ * + * @param the fraction to divide by, must not be null + * @return a Fraction instance with the resulting values + * @throws IllegalArgumentException if the fraction is null + * @throws ArithmeticException if the fraction to divide by is zero + */ + public Fraction divideBy(Fraction fraction) { + if (fraction == null) { + throw new IllegalArgumentException("The fraction must not be null"); + } + if (fraction.numerator == 0) { + throw new ArithmeticException("The fraction to divide by must not be zero"); + } + if (numerator == 0) { + return ZERO; + } + return getReducedFraction( + numerator * fraction.denominator, + denominator * fraction.numerator + ); + } + + // Basics + //------------------------------------------------------------------- + + /** + *

Compares this fraction to another object to test if they are equal.

. + * + *

To be equal, both values must be equal. Thus 2/4 is not equal to 1/2.

+ * + * @param obj the reference object with which to compare + * @return true if this object is equal + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Fraction == false) { + return false; + } + Fraction other = (Fraction) obj; + return (numerator == other.numerator && + denominator == other.denominator); + } + + /** + *

Gets a hashCode for the fraction.

+ * + * @return a hash code value for this object + */ + public int hashCode() { + if (hashCode == 0) { + hashCode = 17; + hashCode = 37 * hashCode + numerator; + hashCode = 37 * hashCode + denominator; + } + return hashCode; + } + + /** + *

Compares this object to another based on size.

+ * + * @param object the object to compare to + * @return -ve if this is less, 0 if equal, +ve if greater + * @throws ClassCastException if the object is not a Fraction + * @throws NullPointerException if the object is null + */ + public int compareTo(Object object) { + Fraction other = (Fraction) object; + if (numerator == other.numerator && denominator == other.denominator) { + return 0; + } + + // otherwise see which is less + long first = (long) numerator * (long) other.denominator; + long second = (long) other.numerator * (long) denominator; + if (first == second) { + return 0; + } else if (first < second) { + return -1; + } else { + return 1; + } + } + + /** + *

Gets the fraction as a String.

+ * + *

The format used is 'numerator/denominator' always. + * + * @return a String form of the fraction + */ + public String toString() { + if (toString == null) { + toString = new StringBuffer(32) + .append(numerator) + .append('/') + .append(denominator).toString(); + } + return toString; + } + + /** + *

Gets the fraction as a proper String in the format X Y/Z.

+ * + *

The format used in 'wholeNumber numerator/denominator'. + * If the whole number is zero it will be ommitted. If the numerator is zero, + * only the whole number is returned.

+ * + * @return a String form of the fraction + */ + public String toProperString() { + if (toProperString == null) { + if (numerator == 0) { + toProperString = "0"; + } else if (numerator == denominator) { + toProperString = "1"; + } else if (Math.abs(numerator) > denominator) { + int properNumerator = getProperNumerator(); + if (properNumerator == 0) { + toProperString = Integer.toString(getProperWhole()); + } else { + toProperString = new StringBuffer(32) + .append(getProperWhole()).append(' ') + .append(properNumerator).append('/') + .append(denominator).toString(); + } + } else { + toProperString = new StringBuffer(32) + .append(numerator).append('/') + .append(denominator).toString(); + } + } + return toProperString; + } + +} diff --git a/src/test/org/apache/commons/lang/math/FractionTest.java b/src/test/org/apache/commons/lang/math/FractionTest.java new file mode 100644 index 000000000..55f16e36f --- /dev/null +++ b/src/test/org/apache/commons/lang/math/FractionTest.java @@ -0,0 +1,888 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.lang.math; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +/** + * Test cases for the {@link Fraction} classes. + * + * @author Stephen Colebourne + * @version $Id: FractionTest.java,v 1.1 2002/12/22 19:39:39 scolebourne Exp $ + */ +public class FractionTest extends TestCase { + + private static final int SKIP = 10000; + + public FractionTest(String name) { + super(name); + } + + public static Test suite() { + TestSuite suite = new TestSuite(FractionTest.class); + suite.setName("Fraction Tests"); + return suite; + } + + public void setUp() { + } + + //-------------------------------------------------------------------------- + + public void testConstants() { + assertEquals(0, Fraction.ZERO.getNumerator()); + assertEquals(1, Fraction.ZERO.getDenominator()); + + assertEquals(1, Fraction.ONE.getNumerator()); + assertEquals(1, Fraction.ONE.getDenominator()); + + assertEquals(1, Fraction.ONE_HALF.getNumerator()); + assertEquals(2, Fraction.ONE_HALF.getDenominator()); + + assertEquals(1, Fraction.ONE_THIRD.getNumerator()); + assertEquals(3, Fraction.ONE_THIRD.getDenominator()); + + assertEquals(2, Fraction.TWO_THIRDS.getNumerator()); + assertEquals(3, Fraction.TWO_THIRDS.getDenominator()); + + assertEquals(1, Fraction.ONE_QUARTER.getNumerator()); + assertEquals(4, Fraction.ONE_QUARTER.getDenominator()); + + assertEquals(2, Fraction.TWO_QUARTERS.getNumerator()); + assertEquals(4, Fraction.TWO_QUARTERS.getDenominator()); + + assertEquals(3, Fraction.THREE_QUARTERS.getNumerator()); + assertEquals(4, Fraction.THREE_QUARTERS.getDenominator()); + + assertEquals(1, Fraction.ONE_FIFTH.getNumerator()); + assertEquals(5, Fraction.ONE_FIFTH.getDenominator()); + + assertEquals(2, Fraction.TWO_FIFTHS.getNumerator()); + assertEquals(5, Fraction.TWO_FIFTHS.getDenominator()); + + assertEquals(3, Fraction.THREE_FIFTHS.getNumerator()); + assertEquals(5, Fraction.THREE_FIFTHS.getDenominator()); + + assertEquals(4, Fraction.FOUR_FIFTHS.getNumerator()); + assertEquals(5, Fraction.FOUR_FIFTHS.getDenominator()); + } + + public void testFactory_int_int() { + Fraction f = null; + + // zero + f = Fraction.getFraction(0, 1); + assertEquals(0, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f = Fraction.getFraction(0, 2); + assertEquals(0, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + // normal + f = Fraction.getFraction(1, 1); + assertEquals(1, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f = Fraction.getFraction(2, 1); + assertEquals(2, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f = Fraction.getFraction(23, 345); + assertEquals(23, f.getNumerator()); + assertEquals(345, f.getDenominator()); + + // improper + f = Fraction.getFraction(22, 7); + assertEquals(22, f.getNumerator()); + assertEquals(7, f.getDenominator()); + + // negatives + f = Fraction.getFraction(-6, 10); + assertEquals(-6, f.getNumerator()); + assertEquals(10, f.getDenominator()); + + f = Fraction.getFraction(6, -10); + assertEquals(-6, f.getNumerator()); + assertEquals(10, f.getDenominator()); + + f = Fraction.getFraction(-6, -10); + assertEquals(6, f.getNumerator()); + assertEquals(10, f.getDenominator()); + + // zero denominator + try { + f = Fraction.getFraction(1, 0); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getFraction(2, 0); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getFraction(-3, 0); + } catch (ArithmeticException ex) {} + } + + public void testFactory_int_int_int() { + Fraction f = null; + + // zero + f = Fraction.getFraction(0, 0, 2); + assertEquals(0, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + f = Fraction.getFraction(2, 0, 2); + assertEquals(4, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + f = Fraction.getFraction(0, 1, 2); + assertEquals(1, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + // normal + f = Fraction.getFraction(1, 1, 2); + assertEquals(3, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + // negatives + try { + f = Fraction.getFraction(1, -6, -10); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getFraction(1, -6, -10); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getFraction(1, -6, -10); + } catch (ArithmeticException ex) {} + + // negative whole + f = Fraction.getFraction(-1, 6, 10); + assertEquals(-16, f.getNumerator()); + assertEquals(10, f.getDenominator()); + + try { + f = Fraction.getFraction(-1, -6, 10); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getFraction(-1, 6, -10); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getFraction(-1, -6, -10); + } catch (ArithmeticException ex) {} + + // zero denominator + try { + f = Fraction.getFraction(0, 1, 0); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getFraction(1, 2, 0); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getFraction(-1, -3, 0); + } catch (ArithmeticException ex) {} + } + + public void testReducedFactory_int_int() { + Fraction f = null; + + // zero + f = Fraction.getReducedFraction(0, 1); + assertEquals(0, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + // normal + f = Fraction.getReducedFraction(1, 1); + assertEquals(1, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f = Fraction.getReducedFraction(2, 1); + assertEquals(2, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + // improper + f = Fraction.getReducedFraction(22, 7); + assertEquals(22, f.getNumerator()); + assertEquals(7, f.getDenominator()); + + // negatives + f = Fraction.getReducedFraction(-6, 10); + assertEquals(-3, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + f = Fraction.getReducedFraction(6, -10); + assertEquals(-3, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + f = Fraction.getReducedFraction(-6, -10); + assertEquals(3, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + // zero denominator + try { + f = Fraction.getReducedFraction(1, 0); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getReducedFraction(2, 0); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getReducedFraction(-3, 0); + } catch (ArithmeticException ex) {} + + // reduced + f = Fraction.getReducedFraction(0, 2); + assertEquals(0, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f = Fraction.getReducedFraction(2, 2); + assertEquals(1, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f = Fraction.getReducedFraction(2, 4); + assertEquals(1, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + f = Fraction.getReducedFraction(15, 10); + assertEquals(3, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + f = Fraction.getReducedFraction(121, 22); + assertEquals(11, f.getNumerator()); + assertEquals(2, f.getDenominator()); + } + + public void testFactory_double() { + Fraction f = null; + + try { + f = Fraction.getFraction(Double.NaN); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getFraction(Double.POSITIVE_INFINITY); + } catch (ArithmeticException ex) {} + + try { + f = Fraction.getFraction(Double.NEGATIVE_INFINITY); + } catch (ArithmeticException ex) {} + + // zero + f = Fraction.getFraction(0.0d); + assertEquals(0, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + // one + f = Fraction.getFraction(1.0d); + assertEquals(1, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + // one half + f = Fraction.getFraction(0.5d); + assertEquals(1, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + // negative + f = Fraction.getFraction(-0.875d); + assertEquals(-7, f.getNumerator()); + assertEquals(8, f.getDenominator()); + + // over 1 + f = Fraction.getFraction(1.25d); + assertEquals(5, f.getNumerator()); + assertEquals(4, f.getDenominator()); + + // two thirds + f = Fraction.getFraction(0.66666d); + assertEquals(2, f.getNumerator()); + assertEquals(3, f.getDenominator()); + + // small + f = Fraction.getFraction(1.0d/10001d); + assertEquals(0, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + // normal + Fraction f2 = null; + int remainder, number1, number2 = 0; + for (int i = 1; i <= 100; i++) { // denominator + for (int j = 1; j <= i; j++) { // numerator + try { + f = Fraction.getFraction((double) j / (double) i); + } catch (ArithmeticException ex) { + System.err.println(j + " " + i); + throw ex; + } + f2 = Fraction.getReducedFraction(j, i); + assertEquals(f2.getNumerator(), f.getNumerator()); + assertEquals(f2.getDenominator(), f.getDenominator()); + } + } + // save time by skipping some tests! + for (int i = 1001; i <= 10000; i+=SKIP) { // denominator + for (int j = 1; j <= i; j++) { // numerator + try { + f = Fraction.getFraction((double) j / (double) i); + } catch (ArithmeticException ex) { + System.err.println(j + " " + i); + throw ex; + } + f2 = Fraction.getReducedFraction(j, i); + assertEquals(f2.getNumerator(), f.getNumerator()); + assertEquals(f2.getDenominator(), f.getDenominator()); + } + } + } + + public void testFactory_String() { + try { + Fraction.getFraction(null); + } catch (IllegalArgumentException ex) {} + } + + public void testFactory_String_double() { + Fraction f = null; + + f = Fraction.getFraction("0.0"); + assertEquals(0, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f = Fraction.getFraction("0.2"); + assertEquals(1, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + f = Fraction.getFraction("0.5"); + assertEquals(1, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + f = Fraction.getFraction("0.66666"); + assertEquals(2, f.getNumerator()); + assertEquals(3, f.getDenominator()); + + try { + f = Fraction.getFraction("2.3R"); + } catch (NumberFormatException ex) {} + + try { + f = Fraction.getFraction("."); + } catch (NumberFormatException ex) {} + } + + public void testFactory_String_proper() { + Fraction f = null; + + f = Fraction.getFraction("0 0/1"); + assertEquals(0, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f = Fraction.getFraction("1 1/5"); + assertEquals(6, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + f = Fraction.getFraction("7 1/2"); + assertEquals(15, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + f = Fraction.getFraction("1 2/4"); + assertEquals(6, f.getNumerator()); + assertEquals(4, f.getDenominator()); + + try { + f = Fraction.getFraction("2 3"); + } catch (NumberFormatException ex) {} + + try { + f = Fraction.getFraction("a 3"); + } catch (NumberFormatException ex) {} + + try { + f = Fraction.getFraction("2 b/4"); + } catch (NumberFormatException ex) {} + + try { + f = Fraction.getFraction("2 "); + } catch (NumberFormatException ex) {} + + try { + f = Fraction.getFraction(" 3"); + } catch (NumberFormatException ex) {} + + try { + f = Fraction.getFraction(" "); + } catch (NumberFormatException ex) {} + } + + public void testFactory_String_improper() { + Fraction f = null; + + f = Fraction.getFraction("0/1"); + assertEquals(0, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f = Fraction.getFraction("1/5"); + assertEquals(1, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + f = Fraction.getFraction("1/2"); + assertEquals(1, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + f = Fraction.getFraction("2/3"); + assertEquals(2, f.getNumerator()); + assertEquals(3, f.getDenominator()); + + f = Fraction.getFraction("7/3"); + assertEquals(7, f.getNumerator()); + assertEquals(3, f.getDenominator()); + + f = Fraction.getFraction("2/4"); + assertEquals(2, f.getNumerator()); + assertEquals(4, f.getDenominator()); + + try { + f = Fraction.getFraction("2/d"); + } catch (NumberFormatException ex) {} + + try { + f = Fraction.getFraction("2e/3"); + } catch (NumberFormatException ex) {} + + try { + f = Fraction.getFraction("2/"); + } catch (NumberFormatException ex) {} + + try { + f = Fraction.getFraction("/"); + } catch (NumberFormatException ex) {} + } + + public void testGets() { + Fraction f = null; + + f = Fraction.getFraction(3, 5, 6); + assertEquals(23, f.getNumerator()); + assertEquals(3, f.getProperWhole()); + assertEquals(5, f.getProperNumerator()); + assertEquals(6, f.getDenominator()); + + f = Fraction.getFraction(-3, 5, 6); + assertEquals(-23, f.getNumerator()); + assertEquals(-3, f.getProperWhole()); + assertEquals(5, f.getProperNumerator()); + assertEquals(6, f.getDenominator()); + } + + public void testConversions() { + Fraction f = null; + + f = Fraction.getFraction(3, 7, 8); + assertEquals(3, f.intValue()); + assertEquals(3L, f.longValue()); + assertEquals(3.875f, f.floatValue(), 0.00001f); + assertEquals(3.875d, f.doubleValue(), 0.00001d); + } + + public void testReduce() { + Fraction f = null; + + f = Fraction.getFraction(50, 75); + f = f.reduce(); + assertEquals(2, f.getNumerator()); + assertEquals(3, f.getDenominator()); + } + + public void testInvert() { + Fraction f = null; + + f = Fraction.getFraction(50, 75); + f = f.invert(); + assertEquals(75, f.getNumerator()); + assertEquals(50, f.getDenominator()); + + f = Fraction.getFraction(4, 3); + f = f.invert(); + assertEquals(3, f.getNumerator()); + assertEquals(4, f.getDenominator()); + + f = Fraction.getFraction(0, 3); + try { + f = f.invert(); + } catch (ArithmeticException ex) {} + } + + public void testNegate() { + Fraction f = null; + + f = Fraction.getFraction(50, 75); + f = f.negate(); + assertEquals(-50, f.getNumerator()); + assertEquals(75, f.getDenominator()); + + f = Fraction.getFraction(-50, 75); + f = f.negate(); + assertEquals(50, f.getNumerator()); + assertEquals(75, f.getDenominator()); + } + + public void testAbs() { + Fraction f = null; + + f = Fraction.getFraction(50, 75); + f = f.abs(); + assertEquals(50, f.getNumerator()); + assertEquals(75, f.getDenominator()); + + f = Fraction.getFraction(-50, 75); + f = f.abs(); + assertEquals(50, f.getNumerator()); + assertEquals(75, f.getDenominator()); + } + + public void testPow() { + Fraction f = null; + + f = Fraction.getFraction(3, 5); + assertEquals(Fraction.ONE, f.pow(0)); + + f = Fraction.getFraction(3, 5); + assertSame(f, f.pow(1)); + + f = Fraction.getFraction(3, 5); + f = f.pow(2); + assertEquals(9, f.getNumerator()); + assertEquals(25, f.getDenominator()); + + f = Fraction.getFraction(3, 5); + f = f.pow(3); + assertEquals(27, f.getNumerator()); + assertEquals(125, f.getDenominator()); + + f = Fraction.getFraction(3, 5); + f = f.pow(-1); + assertEquals(5, f.getNumerator()); + assertEquals(3, f.getDenominator()); + + f = Fraction.getFraction(3, 5); + f = f.pow(-2); + assertEquals(25, f.getNumerator()); + assertEquals(9, f.getDenominator()); + } + + public void testAdd() { + Fraction f = null; + Fraction f1 = null; + Fraction f2 = null; + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(1, 5); + f = f1.add(f2); + assertEquals(4, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(2, 5); + f = f1.add(f2); + assertEquals(1, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(3, 5); + f = f1.add(f2); + assertEquals(6, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(-4, 5); + f = f1.add(f2); + assertEquals(-1, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(1, 2); + f = f1.add(f2); + assertEquals(11, f.getNumerator()); + assertEquals(10, f.getDenominator()); + + f1 = Fraction.getFraction(0, 5); + f2 = Fraction.getFraction(1, 5); + f = f1.add(f2); + assertSame(f2, f); + f = f2.add(f1); + assertSame(f2, f); + + try { + f.add(null); + } catch (IllegalArgumentException ex) {} + } + + public void testSubtract() { + Fraction f = null; + Fraction f1 = null; + Fraction f2 = null; + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(1, 5); + f = f1.subtract(f2); + assertEquals(2, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + f1 = Fraction.getFraction(7, 5); + f2 = Fraction.getFraction(2, 5); + f = f1.subtract(f2); + assertEquals(1, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(3, 5); + f = f1.subtract(f2); + assertEquals(0, f.getNumerator()); + assertEquals(1, f.getDenominator()); + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(-4, 5); + f = f1.subtract(f2); + assertEquals(7, f.getNumerator()); + assertEquals(5, f.getDenominator()); + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(1, 2); + f = f1.subtract(f2); + assertEquals(1, f.getNumerator()); + assertEquals(10, f.getDenominator()); + + f1 = Fraction.getFraction(0, 5); + f2 = Fraction.getFraction(1, 5); + f = f2.subtract(f1); + assertSame(f2, f); + + try { + f.subtract(null); + } catch (IllegalArgumentException ex) {} + } + + public void testMultiply() { + Fraction f = null; + Fraction f1 = null; + Fraction f2 = null; + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(2, 5); + f = f1.multiplyBy(f2); + assertEquals(6, f.getNumerator()); + assertEquals(25, f.getDenominator()); + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(-2, 5); + f = f1.multiplyBy(f2); + assertEquals(-6, f.getNumerator()); + assertEquals(25, f.getDenominator()); + + f1 = Fraction.getFraction(-3, 5); + f2 = Fraction.getFraction(-2, 5); + f = f1.multiplyBy(f2); + assertEquals(6, f.getNumerator()); + assertEquals(25, f.getDenominator()); + + f1 = Fraction.getFraction(0, 5); + f2 = Fraction.getFraction(2, 7); + f = f1.multiplyBy(f2); + assertSame(Fraction.ZERO, f); + + try { + f.multiplyBy(null); + } catch (IllegalArgumentException ex) {} + } + + public void testDivide() { + Fraction f = null; + Fraction f1 = null; + Fraction f2 = null; + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(2, 5); + f = f1.divideBy(f2); + assertEquals(3, f.getNumerator()); + assertEquals(2, f.getDenominator()); + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.ZERO; + try { + f = f1.divideBy(f2); + } catch (ArithmeticException ex) {} + + f1 = Fraction.getFraction(0, 5); + f2 = Fraction.getFraction(2, 7); + f = f1.divideBy(f2); + assertSame(Fraction.ZERO, f); + + try { + f.divideBy(null); + } catch (IllegalArgumentException ex) {} + } + + public void testEquals() { + Fraction f1 = null; + Fraction f2 = null; + + f1 = Fraction.getFraction(3, 5); + assertEquals(false, f1.equals(null)); + assertEquals(false, f1.equals(new Object())); + assertEquals(false, f1.equals(new Integer(6))); + + f1 = Fraction.getFraction(3, 5); + f2 = Fraction.getFraction(2, 5); + assertEquals(false, f1.equals(f2)); + assertEquals(true, f1.equals(f1)); + assertEquals(true, f2.equals(f2)); + + f2 = Fraction.getFraction(3, 5); + assertEquals(true, f1.equals(f2)); + + f2 = Fraction.getFraction(6, 10); + assertEquals(false, f1.equals(f2)); + } + + public void testHashCode() { + Fraction f1 = Fraction.getFraction(3, 5); + Fraction f2 = Fraction.getFraction(3, 5); + + assertTrue(f1.hashCode() == f2.hashCode()); + + f2 = Fraction.getFraction(2, 5); + assertTrue(f1.hashCode() != f2.hashCode()); + + f2 = Fraction.getFraction(6, 10); + assertTrue(f1.hashCode() != f2.hashCode()); + } + + public void testCompareTo() { + Fraction f1 = null; + Fraction f2 = null; + + f1 = Fraction.getFraction(3, 5); + + try { + f1.compareTo(null); + } catch (NullPointerException ex) {} + + try { + f1.compareTo(new Object()); + } catch (ClassCastException ex) {} + + f2 = Fraction.getFraction(2, 5); + assertTrue(f1.compareTo(f2) > 0); + + f2 = Fraction.getFraction(4, 5); + assertTrue(f1.compareTo(f2) < 0); + + f2 = Fraction.getFraction(3, 5); + assertTrue(f1.compareTo(f2) == 0); + + f2 = Fraction.getFraction(6, 10); + assertTrue(f1.compareTo(f2) == 0); + } + + public void testToString() { + Fraction f = null; + + f = Fraction.getFraction(3, 5); + assertEquals("3/5", f.toString()); + + f = Fraction.getFraction(7, 5); + assertEquals("7/5", f.toString()); + + f = Fraction.getFraction(4, 2); + assertEquals("4/2", f.toString()); + + f = Fraction.getFraction(0, 2); + assertEquals("0/2", f.toString()); + + f = Fraction.getFraction(2, 2); + assertEquals("2/2", f.toString()); + } + + public void testToProperString() { + Fraction f = null; + + f = Fraction.getFraction(3, 5); + assertEquals("3/5", f.toProperString()); + + f = Fraction.getFraction(7, 5); + assertEquals("1 2/5", f.toProperString()); + + f = Fraction.getFraction(14, 10); + assertEquals("1 4/10", f.toProperString()); + + f = Fraction.getFraction(4, 2); + assertEquals("2", f.toProperString()); + + f = Fraction.getFraction(0, 2); + assertEquals("0", f.toProperString()); + + f = Fraction.getFraction(2, 2); + assertEquals("1", f.toProperString()); + + f = Fraction.getFraction(-7, 5); + assertEquals("-1 2/5", f.toProperString()); + } + +} diff --git a/src/test/org/apache/commons/lang/math/MathTestSuite.java b/src/test/org/apache/commons/lang/math/MathTestSuite.java index 433db6c2e..bbd14c8ed 100644 --- a/src/test/org/apache/commons/lang/math/MathTestSuite.java +++ b/src/test/org/apache/commons/lang/math/MathTestSuite.java @@ -61,7 +61,7 @@ import junit.textui.TestRunner; * Test suite for the Math package. * * @author Stephen Colebourne - * @version $Id: MathTestSuite.java,v 1.1 2002/12/22 16:20:29 scolebourne Exp $ + * @version $Id: MathTestSuite.java,v 1.2 2002/12/22 19:39:39 scolebourne Exp $ */ public class MathTestSuite extends TestCase { @@ -87,6 +87,7 @@ public class MathTestSuite extends TestCase { suite.setName("Commons-Lang-Math Tests"); suite.addTest(DoubleRangeTest.suite()); suite.addTest(FloatRangeTest.suite()); + suite.addTest(FractionTest.suite()); suite.addTest(IntRangeTest.suite()); suite.addTest(LongRangeTest.suite()); suite.addTest(NumberRangeTest.suite());