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)));
+    }
+
 }