Added add/subtract/multiply/divide functions with integer parameters to Fraction

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@760867 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2009-04-01 12:15:29 +00:00
parent 80419081ac
commit 3664a2cc7f
4 changed files with 113 additions and 15 deletions

View File

@ -31,11 +31,17 @@ import org.apache.commons.math.util.MathUtils;
*/ */
public class BigFraction extends Number implements Comparable<BigFraction> { public class BigFraction extends Number implements Comparable<BigFraction> {
/** A fraction representing "2 / 1". */
public static final BigFraction TWO = new BigFraction(2);
/** A fraction representing "1". */ /** A fraction representing "1". */
public static final BigFraction ONE = new BigFraction(1, 1); public static final BigFraction ONE = new BigFraction(1);
/** A fraction representing "0". */ /** A fraction representing "0". */
public static final BigFraction ZERO = new BigFraction(0, 1); public static final BigFraction ZERO = new BigFraction(0);
/** A fraction representing "-1 / 1". */
public static final BigFraction MINUS_ONE = new BigFraction(-1);
/** A fraction representing "4/5". */ /** A fraction representing "4/5". */
public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5); public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5);
@ -67,11 +73,8 @@ public class BigFraction extends Number implements Comparable<BigFraction> {
/** A fraction representing "2/3". */ /** A fraction representing "2/3". */
public static final BigFraction TWO_THIRDS = new BigFraction(2, 3); public static final BigFraction TWO_THIRDS = new BigFraction(2, 3);
/** A fraction representing "-1 / 1". */
public static final BigFraction MINUS_ONE = new BigFraction(-1, 1);
/** Serializable version identifier. */ /** Serializable version identifier. */
private static final long serialVersionUID = -5984892138972589598L; private static final long serialVersionUID = -130662482360701382L;
/** <code>BigInteger</code> representation of 100. */ /** <code>BigInteger</code> representation of 100. */
private static final BigInteger ONE_HUNDRED_DOUBLE = BigInteger.valueOf(100); private static final BigInteger ONE_HUNDRED_DOUBLE = BigInteger.valueOf(100);

View File

@ -32,12 +32,42 @@ public class Fraction extends Number implements Comparable<Fraction> {
/** A fraction representing "2 / 1". */ /** A fraction representing "2 / 1". */
public static final Fraction TWO = new Fraction(2, 1); public static final Fraction TWO = new Fraction(2, 1);
/** A fraction representing "1 / 1". */ /** A fraction representing "1". */
public static final Fraction ONE = new Fraction(1, 1); public static final Fraction ONE = new Fraction(1, 1);
/** A fraction representing "0 / 1". */ /** A fraction representing "0". */
public static final Fraction ZERO = new Fraction(0, 1); public static final Fraction ZERO = new Fraction(0, 1);
/** A fraction representing "4/5". */
public static final Fraction FOUR_FIFTHS = new Fraction(4, 5);
/** A fraction representing "1/5". */
public static final Fraction ONE_FIFTH = new Fraction(1, 5);
/** A fraction representing "1/2". */
public static final Fraction ONE_HALF = new Fraction(1, 2);
/** A fraction representing "1/4". */
public static final Fraction ONE_QUARTER = new Fraction(1, 4);
/** A fraction representing "1/3". */
public static final Fraction ONE_THIRD = new Fraction(1, 3);
/** A fraction representing "3/5". */
public static final Fraction THREE_FIFTHS = new Fraction(3, 5);
/** A fraction representing "3/4". */
public static final Fraction THREE_QUARTERS = new Fraction(3, 4);
/** A fraction representing "4/5". */
public static final Fraction TWO_FIFTHS = new Fraction(4, 5);
/** A fraction representing "2/4". */
public static final Fraction TWO_QUARTERS = new Fraction(2, 4);
/** A fraction representing "2/3". */
public static final Fraction TWO_THIRDS = new Fraction(2, 3);
/** A fraction representing "-1 / 1". */ /** A fraction representing "-1 / 1". */
public static final Fraction MINUS_ONE = new Fraction(-1, 1); public static final Fraction MINUS_ONE = new Fraction(-1, 1);
@ -198,6 +228,15 @@ public class Fraction extends Number implements Comparable<Fraction> {
} }
/**
* Create a fraction from an int.
* The fraction is num / 1.
* @param num the numerator.
*/
public Fraction(int num) {
this(num, 1);
}
/** /**
* Create a fraction given the numerator and denominator. The fraction is * Create a fraction given the numerator and denominator. The fraction is
* reduced to lowest terms. * reduced to lowest terms.
@ -206,7 +245,6 @@ public class Fraction extends Number implements Comparable<Fraction> {
* @throws ArithmeticException if the denominator is <code>zero</code> * @throws ArithmeticException if the denominator is <code>zero</code>
*/ */
public Fraction(int num, int den) { public Fraction(int num, int den) {
super();
if (den == 0) { if (den == 0) {
throw MathRuntimeException.createArithmeticException("zero denominator in fraction {0}/{1}", throw MathRuntimeException.createArithmeticException("zero denominator in fraction {0}/{1}",
num, den); num, den);
@ -220,7 +258,7 @@ public class Fraction extends Number implements Comparable<Fraction> {
den = -den; den = -den;
} }
// reduce numerator and denominator by greatest common denominator. // reduce numerator and denominator by greatest common denominator.
int d = MathUtils.gcd(num, den); final int d = MathUtils.gcd(num, den);
if (d > 1) { if (d > 1) {
num /= d; num /= d;
den /= d; den /= d;
@ -228,8 +266,8 @@ public class Fraction extends Number implements Comparable<Fraction> {
// move sign to numerator. // move sign to numerator.
if (den < 0) { if (den < 0) {
num *= -1; num = -num;
den *= -1; den = -den;
} }
this.numerator = num; this.numerator = num;
this.denominator = den; this.denominator = den;
@ -387,6 +425,15 @@ public class Fraction extends Number implements Comparable<Fraction> {
return addSub(fraction, true /* add */); return addSub(fraction, true /* add */);
} }
/**
* Add an integer to the fraction.
* @param i the <tt>integer</tt> to add.
* @return this + i
*/
public Fraction add(final int i) {
return new Fraction(numerator + i * denominator, denominator);
}
/** /**
* <p>Subtracts the value of another fraction from the value of this one, * <p>Subtracts the value of another fraction from the value of this one,
* returning the result in reduced form.</p> * returning the result in reduced form.</p>
@ -401,6 +448,15 @@ public class Fraction extends Number implements Comparable<Fraction> {
return addSub(fraction, false /* subtract */); return addSub(fraction, false /* subtract */);
} }
/**
* Subtract an integer from the fraction.
* @param i the <tt>integer</tt> to subtract.
* @return this - i
*/
public Fraction subtract(final int i) {
return new Fraction(numerator - i * denominator, denominator);
}
/** /**
* Implement add and subtract using algorithm described in Knuth 4.5.1. * Implement add and subtract using algorithm described in Knuth 4.5.1.
* *
@ -484,6 +540,15 @@ public class Fraction extends Number implements Comparable<Fraction> {
MathUtils.mulAndCheck(denominator/d2, fraction.denominator/d1)); MathUtils.mulAndCheck(denominator/d2, fraction.denominator/d1));
} }
/**
* Multiply the fraction by an integer.
* @param i the <tt>integer</tt> to multiply by.
* @return this * i
*/
public Fraction multiply(final int i) {
return new Fraction(numerator * i, denominator);
}
/** /**
* <p>Divide the value of this fraction by another.</p> * <p>Divide the value of this fraction by another.</p>
* *
@ -506,6 +571,15 @@ public class Fraction extends Number implements Comparable<Fraction> {
return multiply(fraction.reciprocal()); return multiply(fraction.reciprocal());
} }
/**
* Divide the fraction by an integer.
* @param i the <tt>integer</tt> to divide by.
* @return this * i
*/
public Fraction divide(final int i) {
return new Fraction(numerator, denominator * i);
}
/** /**
* <p>Creates a <code>Fraction</code> instance with the 2 parts * <p>Creates a <code>Fraction</code> instance with the 2 parts
* of a fraction Y/Z.</p> * of a fraction Y/Z.</p>
@ -546,4 +620,5 @@ public class Fraction extends Number implements Comparable<Fraction> {
denominator /= gcd; denominator /= gcd;
return new Fraction(numerator, denominator); return new Fraction(numerator, denominator);
} }
} }

View File

@ -39,6 +39,9 @@ The <action> type attribute can be add,update,fix,remove.
</properties> </properties>
<body> <body>
<release version="2.0" date="TBD" description="TBD"> <release version="2.0" date="TBD" description="TBD">
<action dev="luc" type="add">
Added add/subtract/multiply/divide functions with integer parameters to Fraction
</action>
<action dev="luc" type="add"> <action dev="luc" type="add">
Added some utility functions to compute powers with integral types (int, long, BigInteger). Added some utility functions to compute powers with integral types (int, long, BigInteger).
</action> </action>

View File

@ -308,6 +308,9 @@ public class FractionTest extends TestCase {
Fraction f = f1.add(f2); Fraction f = f1.add(f2);
assertEquals(Integer.MAX_VALUE, f.getNumerator()); assertEquals(Integer.MAX_VALUE, f.getNumerator());
assertEquals(1, f.getDenominator()); assertEquals(1, f.getDenominator());
f = f1.add(1);
assertEquals(Integer.MAX_VALUE, f.getNumerator());
assertEquals(1, f.getDenominator());
f1 = new Fraction(-1, 13*13*2*2); f1 = new Fraction(-1, 13*13*2*2);
f2 = new Fraction(-2, 13*17*2); f2 = new Fraction(-2, 13*17*2);
@ -426,6 +429,12 @@ public class FractionTest extends TestCase {
f = f1.divide(f1.reciprocal()); // should overflow f = f1.divide(f1.reciprocal()); // should overflow
fail("expecting ArithmeticException"); fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {} } catch (ArithmeticException ex) {}
f1 = new Fraction(6, 35);
f = f1.divide(15);
assertEquals(2, f.getNumerator());
assertEquals(175, f.getDenominator());
} }
public void testMultiply() { public void testMultiply() {
@ -447,6 +456,11 @@ public class FractionTest extends TestCase {
f.multiply(null); f.multiply(null);
fail("expecting IllegalArgumentException"); fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException ex) {} } catch (IllegalArgumentException ex) {}
f1 = new Fraction(6, 35);
f = f1.multiply(15);
assertEquals(18, f.getNumerator());
assertEquals(7, f.getDenominator());
} }
public void testSubtract() { public void testSubtract() {
@ -483,6 +497,9 @@ public class FractionTest extends TestCase {
f = f1.subtract(f2); f = f1.subtract(f2);
assertEquals(Integer.MAX_VALUE-1, f.getNumerator()); assertEquals(Integer.MAX_VALUE-1, f.getNumerator());
assertEquals(1, f.getDenominator()); assertEquals(1, f.getDenominator());
f = f1.subtract(1);
assertEquals(Integer.MAX_VALUE-1, f.getNumerator());
assertEquals(1, f.getDenominator());
try { try {
f1 = new Fraction(1, Integer.MAX_VALUE); f1 = new Fraction(1, Integer.MAX_VALUE);