You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2009/03/30 17:48:57 UTC
svn commit: r760016 - in /commons/proper/math/trunk/src:
java/org/apache/commons/math/fraction/BigFraction.java
test/org/apache/commons/math/fraction/BigFractionTest.java
Author: luc
Date: Mon Mar 30 15:48:56 2009
New Revision: 760016
URL: http://svn.apache.org/viewvc?rev=760016&view=rev
Log:
optimized some fraction operations (mainly pow)
replaced pow(BigFraction) by pow(double) as it already converted the argument to double upon entry
added tests for pow
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/BigFraction.java
commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/BigFractionTest.java
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/BigFraction.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/BigFraction.java?rev=760016&r1=760015&r2=760016&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/BigFraction.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/fraction/BigFraction.java Mon Mar 30 15:48:56 2009
@@ -20,6 +20,7 @@
import java.math.BigInteger;
import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.util.MathUtils;
/**
* Representation of a rational number without any overflow. This class is
@@ -457,7 +458,35 @@
* if the {@link BigInteger} is <code>null</code>.
*/
public BigFraction add(final BigInteger bg) {
- return add(new BigFraction(bg, BigInteger.ONE));
+ return new BigFraction(numerator.add(denominator.multiply(bg)), denominator);
+ }
+
+ /**
+ * <p>
+ * Adds the value of this fraction to the passed <tt>integer</tt>, returning
+ * the result in reduced form.
+ * </p>
+ *
+ * @param i
+ * the <tt>integer</tt> to add.
+ * @return a <code>BigFraction</code> instance with the resulting values.
+ */
+ public BigFraction add(final int i) {
+ return add(BigInteger.valueOf(i));
+ }
+
+ /**
+ * <p>
+ * Adds the value of this fraction to the passed <tt>long</tt>, returning
+ * the result in reduced form.
+ * </p>
+ *
+ * @param l
+ * the <tt>long</tt> to add.
+ * @return a <code>BigFraction</code> instance with the resulting values.
+ */
+ public BigFraction add(final long l) {
+ return add(BigInteger.valueOf(l));
}
/**
@@ -493,34 +522,6 @@
/**
* <p>
- * Adds the value of this fraction to the passed <tt>integer</tt>, returning
- * the result in reduced form.
- * </p>
- *
- * @param i
- * the <tt>integer</tt> to add.
- * @return a <code>BigFraction</code> instance with the resulting values.
- */
- public BigFraction add(final int i) {
- return add(new BigFraction(i, 1));
- }
-
- /**
- * <p>
- * Adds the value of this fraction to the passed <tt>long</tt>, returning
- * the result in reduced form.
- * </p>
- *
- * @param l
- * the <tt>long</tt> to add.
- * @return a <code>BigFraction</code> instance with the resulting values.
- */
- public BigFraction add(final long l) {
- return add(new BigFraction(l, 1L));
- }
-
- /**
- * <p>
* Gets the fraction as a <code>BigDecimal</code>. This calculates the
* fraction as the numerator divided by denominator.
* </p>
@@ -602,31 +603,14 @@
* @return a {@link BigFraction} instance with the resulting values.
* @throws NullPointerException
* if the <code>BigInteger</code> is <code>null</code>.
- */
- public BigFraction divide(final BigInteger bg) {
- return divide(new BigFraction(bg, BigInteger.ONE));
- }
-
- /**
- * <p>
- * Divide the value of this fraction by another, returning the result in
- * reduced form.
- * </p>
- *
- * @param fraction
- * the fraction to divide by, must not be <code>null</code>.
- * @return a {@link BigFraction} instance with the resulting values.
- * @throws NullPointerException
- * if the fraction is <code>null</code>.
* @throws ArithmeticException
* if the fraction to divide by is zero.
*/
- public BigFraction divide(final BigFraction fraction) {
- if (BigInteger.ZERO.equals(fraction.numerator)) {
+ public BigFraction divide(final BigInteger bg) {
+ if (BigInteger.ZERO.equals(bg)) {
throw MathRuntimeException.createArithmeticException("denominator must be different from 0");
}
-
- return multiply(fraction.reciprocal());
+ return new BigFraction(numerator, denominator.multiply(bg));
}
/**
@@ -638,9 +622,11 @@
* @param i
* the <tt>int</tt> to divide by.
* @return a {@link BigFraction} instance with the resulting values.
+ * @throws ArithmeticException
+ * if the fraction to divide by is zero.
*/
public BigFraction divide(final int i) {
- return divide(new BigFraction(i, 1));
+ return divide(BigInteger.valueOf(i));
}
/**
@@ -652,9 +638,33 @@
* @param l
* the <tt>long</tt> to divide by.
* @return a {@link BigFraction} instance with the resulting values.
+ * @throws ArithmeticException
+ * if the fraction to divide by is zero.
*/
public BigFraction divide(final long l) {
- return divide(new BigFraction(l, 1L));
+ return divide(BigInteger.valueOf(l));
+ }
+
+ /**
+ * <p>
+ * Divide the value of this fraction by another, returning the result in
+ * reduced form.
+ * </p>
+ *
+ * @param fraction
+ * the fraction to divide by, must not be <code>null</code>.
+ * @return a {@link BigFraction} instance with the resulting values.
+ * @throws NullPointerException
+ * if the fraction is <code>null</code>.
+ * @throws ArithmeticException
+ * if the fraction to divide by is zero.
+ */
+ public BigFraction divide(final BigFraction fraction) {
+ if (BigInteger.ZERO.equals(fraction.numerator)) {
+ throw MathRuntimeException.createArithmeticException("denominator must be different from 0");
+ }
+
+ return multiply(fraction.reciprocal());
}
/**
@@ -840,28 +850,6 @@
/**
* <p>
- * Multiplies the value of this fraction by another, returning the result in
- * reduced form.
- * </p>
- *
- * @param fraction
- * the fraction to multiply by, must not be <code>null</code>.
- * @return a {@link BigFraction} instance with the resulting values.
- * @throws NullPointerException
- * if the fraction is <code>null</code>.
- */
- public BigFraction multiply(final BigFraction fraction) {
- BigFraction ret = ZERO;
-
- if (getNumeratorAsInt() != 0 && fraction.getNumeratorAsInt() != 0) {
- ret = new BigFraction(numerator.multiply(fraction.numerator), denominator.multiply(fraction.denominator));
- }
-
- return ret;
- }
-
- /**
- * <p>
* Multiply the value of this fraction by the passed <tt>int</tt>, returning
* the result in reduced form.
* </p>
@@ -871,7 +859,7 @@
* @return a {@link BigFraction} instance with the resulting values.
*/
public BigFraction multiply(final int i) {
- return multiply(new BigFraction(i, 1));
+ return multiply(BigInteger.valueOf(i));
}
/**
@@ -885,7 +873,29 @@
* @return a {@link BigFraction} instance with the resulting values.
*/
public BigFraction multiply(final long l) {
- return multiply(new BigFraction(l, 1L));
+ return multiply(BigInteger.valueOf(l));
+ }
+
+ /**
+ * <p>
+ * Multiplies the value of this fraction by another, returning the result in
+ * reduced form.
+ * </p>
+ *
+ * @param fraction
+ * the fraction to multiply by, must not be <code>null</code>.
+ * @return a {@link BigFraction} instance with the resulting values.
+ * @throws NullPointerException
+ * if the fraction is <code>null</code>.
+ */
+ public BigFraction multiply(final BigFraction fraction) {
+ BigFraction ret = ZERO;
+
+ if (getNumeratorAsInt() != 0 && fraction.getNumeratorAsInt() != 0) {
+ ret = new BigFraction(numerator.multiply(fraction.numerator), denominator.multiply(fraction.denominator));
+ }
+
+ return ret;
}
/**
@@ -914,26 +924,20 @@
/**
* <p>
- * Returns a <code>BigFraction</code> whose value is
+ * Returns a <tt>integer</tt> whose value is
* <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
* </p>
*
* @param exponent
- * exponent to which this <code>BigFraction</code> is to be raised.
- * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
+ * exponent to which this <code>BigInteger</code> is to be
+ * raised.
+ * @return <tt>this<sup>exponent</sup></tt>.
*/
- public BigFraction pow(final BigInteger exponent) {
- BigFraction ret = this;
- if (!BigInteger.ONE.equals(exponent)) {
- ret = ONE;
- if (!BigInteger.ZERO.equals(exponent)) {
- for (BigInteger bg = BigInteger.ONE; bg.compareTo(exponent) < 0; bg = bg.add(BigInteger.ONE)) {
- ret = ret.multiply(this);
- }
- }
+ public BigFraction pow(final int exponent) {
+ if (exponent < 0) {
+ return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
}
-
- return ret;
+ return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
}
/**
@@ -944,39 +948,50 @@
*
* @param exponent
* exponent to which this <code>BigFraction</code> is to be raised.
- * @return <tt>this<sup>exponent</sup></tt>.
+ * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
*/
- public double pow(final BigFraction exponent) {
- return Math.pow(numerator.doubleValue(), exponent.doubleValue()) / Math.pow(denominator.doubleValue(), exponent.doubleValue());
+ public BigFraction pow(final long exponent) {
+ if (exponent < 0) {
+ return new BigFraction(MathUtils.pow(denominator, -exponent),
+ MathUtils.pow(numerator, -exponent));
+ }
+ return new BigFraction(MathUtils.pow(numerator, exponent),
+ MathUtils.pow(denominator, exponent));
}
-
+
/**
* <p>
- * Returns a <tt>integer</tt> whose value is
+ * Returns a <code>BigFraction</code> whose value is
* <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
* </p>
*
* @param exponent
- * exponent to which this <code>BigInteger</code> is to be
- * raised.
- * @return <tt>this<sup>exponent</sup></tt>.
+ * exponent to which this <code>BigFraction</code> is to be raised.
+ * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
*/
- public BigFraction pow(final int exponent) {
- return pow(BigInteger.valueOf(exponent));
+ public BigFraction pow(final BigInteger exponent) {
+ if (exponent.compareTo(BigInteger.ZERO) < 0) {
+ final BigInteger eNeg = exponent.negate();
+ return new BigFraction(MathUtils.pow(denominator, eNeg),
+ MathUtils.pow(numerator, eNeg));
+ }
+ return new BigFraction(MathUtils.pow(numerator, exponent),
+ MathUtils.pow(denominator, exponent));
}
/**
* <p>
- * Returns a <code>BigFraction</code> whose value is
+ * Returns a <code>double</code> whose value is
* <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
* </p>
*
* @param exponent
* exponent to which this <code>BigFraction</code> is to be raised.
- * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
+ * @return <tt>this<sup>exponent</sup></tt>.
*/
- public BigFraction pow(final long exponent) {
- return pow(BigInteger.valueOf(exponent));
+ public double pow(final double exponent) {
+ return Math.pow(numerator.doubleValue(), exponent) /
+ Math.pow(denominator.doubleValue(), exponent);
}
/**
@@ -1017,7 +1032,36 @@
* if the {@link BigInteger} is <code>null</code>.
*/
public BigFraction subtract(final BigInteger bg) {
- return subtract(new BigFraction(bg, BigInteger.valueOf(1)));
+ return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
+ }
+
+ /**
+ * <p>
+ * Subtracts the value of an <tt>integer</tt> from the value of this one,
+ * returning the result in reduced form.
+ * </p>
+ *
+ * @param i
+ * the <tt>integer</tt> to subtract.
+ * @return a <code>BigFraction</code> instance with the resulting values.
+ */
+ public BigFraction subtract(final int i) {
+ return subtract(BigInteger.valueOf(i));
+ }
+
+ /**
+ * <p>
+ * Subtracts the value of an <tt>integer</tt> from the value of this one,
+ * returning the result in reduced form.
+ * </p>
+ *
+ * @param l
+ * the <tt>long</tt> to subtract.
+ * @return a <code>BigFraction</code> instance with the resulting values, or
+ * this object if the <tt>long</tt> is zero.
+ */
+ public BigFraction subtract(final long l) {
+ return subtract(BigInteger.valueOf(l));
}
/**
@@ -1053,35 +1097,6 @@
/**
* <p>
- * Subtracts the value of an <tt>integer</tt> from the value of this one,
- * returning the result in reduced form.
- * </p>
- *
- * @param i
- * the <tt>integer</tt> to subtract.
- * @return a <code>BigFraction</code> instance with the resulting values.
- */
- public BigFraction subtract(final int i) {
- return subtract(new BigFraction(i, 1));
- }
-
- /**
- * <p>
- * Subtracts the value of an <tt>integer</tt> from the value of this one,
- * returning the result in reduced form.
- * </p>
- *
- * @param l
- * the <tt>long</tt> to subtract.
- * @return a <code>BigFraction</code> instance with the resulting values, or
- * this object if the <tt>long</tt> is zero.
- */
- public BigFraction subtract(final long l) {
- return subtract(new BigFraction(l, 1L));
- }
-
- /**
- * <p>
* Returns the <code>String</code> representing this fraction, ie
* "num / dem" or just "num" if the denominator is one.
* </p>
Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/BigFractionTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/BigFractionTest.java?rev=760016&r1=760015&r2=760016&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/BigFractionTest.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/BigFractionTest.java Mon Mar 30 15:48:56 2009
@@ -537,4 +537,17 @@
assertEquals(BigFraction.getReducedFraction(2, Integer.MIN_VALUE).getNumeratorAsInt(), -1);
assertEquals(BigFraction.getReducedFraction(1, -1).getNumeratorAsInt(), -1);
}
+
+ public void testPow() {
+ assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(13));
+ assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(13l));
+ assertEquals(new BigFraction(8192, 1594323), new BigFraction(2, 3).pow(BigInteger.valueOf(13l)));
+ assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(0));
+ assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(0l));
+ assertEquals(BigFraction.ONE, new BigFraction(2, 3).pow(BigInteger.valueOf(0l)));
+ assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(-13));
+ assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(-13l));
+ assertEquals(new BigFraction(1594323, 8192), new BigFraction(2, 3).pow(BigInteger.valueOf(-13l)));
+ }
+
}