commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pste...@apache.org
Subject svn commit: r735781 - in /commons/proper/math/trunk/src: java/org/apache/commons/math/util/MathUtils.java site/xdoc/changes.xml test/org/apache/commons/math/util/MathUtilsTest.java
Date Mon, 19 Jan 2009 19:43:01 GMT
Author: psteitz
Date: Mon Jan 19 11:43:01 2009
New Revision: 735781

URL: http://svn.apache.org/viewvc?rev=735781&view=rev
Log:
Fixed error in factorial accuracy.  JIRA: MATH-240.

Modified:
    commons/proper/math/trunk/src/java/org/apache/commons/math/util/MathUtils.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    commons/proper/math/trunk/src/test/org/apache/commons/math/util/MathUtilsTest.java

Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/util/MathUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/util/MathUtils.java?rev=735781&r1=735780&r2=735781&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/util/MathUtils.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/util/MathUtils.java Mon Jan
19 11:43:01 2009
@@ -311,6 +311,13 @@
         }
         return true;
     }
+    
+    /** All long-representable factorials */
+    private static final long[] factorials = new long[] 
+       {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800,
+        479001600, 6227020800l, 87178291200l, 1307674368000l, 20922789888000l,
+        355687428096000l, 6402373705728000l, 121645100408832000l,
+        2432902008176640000l};
 
     /**
      * Returns n!. Shorthand for <code>n</code> <a
@@ -335,12 +342,14 @@
      * @throws IllegalArgumentException if n < 0
      */
     public static long factorial(final int n) {
-        long result = Math.round(factorialDouble(n));
-        if (result == Long.MAX_VALUE) {
+        if (n < 0) {
+            throw new IllegalArgumentException("must have n >= 0 for n!");
+        }
+        if (n > 20) {
             throw new ArithmeticException(
-                "result too large to represent in a long integer");
+                    "factorial value is too large to fit in a long");
         }
-        return result;
+        return factorials[n];
     }
 
     /**
@@ -367,6 +376,9 @@
         if (n < 0) {
             throw new IllegalArgumentException("must have n >= 0 for n!");
         }
+        if (n < 21) {
+            return factorial(n);
+        }
         return Math.floor(Math.exp(factorialLog(n)) + 0.5);
     }
 
@@ -387,6 +399,9 @@
         if (n < 0) {
             throw new IllegalArgumentException("must have n > 0 for n!");
         }
+        if (n < 21) {
+            return Math.log(factorial(n));
+        }
         double logSum = 0;
         for (int i = 2; i <= n; i++) {
             logSum += Math.log((double)i);

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=735781&r1=735780&r2=735781&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Mon Jan 19 11:43:01 2009
@@ -39,6 +39,9 @@
   </properties>
   <body>
     <release version="2.0" date="TBD" description="TBD">
+      <action dev="psteitz" type="fix" issue="MATH-240" due-to="Christian Semrau">
+        Fixed error in factorial computation for 17 <= n <= 20.
+      </action>
       <action dev="luc" type="update" >
         Integration algorithms now can have both relative and absolute
         accuracy settings.
@@ -49,7 +52,7 @@
       <action dev="luc" type="update" >
         The analysis package has been reorganized with several sub-packages.
       </action>
-      <action dev="luc" type="fix" issue="MATH-238" due-to="Chritian Semrau">
+      <action dev="luc" type="fix" issue="MATH-238" due-to="Christian Semrau">
         Fixed an error in gcd computation for large values.
       </action>
       <action dev="luc" type="add" >

Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/util/MathUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/util/MathUtilsTest.java?rev=735781&r1=735780&r2=735781&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/util/MathUtilsTest.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/util/MathUtilsTest.java Mon
Jan 19 11:43:01 2009
@@ -232,11 +232,12 @@
     }
 
     public void testFactorial() {
-        for (int i = 1; i < 10; i++) {
+        for (int i = 1; i < 21; i++) {
             assertEquals(i + "! ", factorial(i), MathUtils.factorial(i));
             assertEquals(i + "! ", (double)factorial(i), MathUtils.factorialDouble(i), Double.MIN_VALUE);
             assertEquals(i + "! ", Math.log((double)factorial(i)), MathUtils.factorialLog(i),
10E-12);
         }
+        
         assertEquals("0", 1, MathUtils.factorial(0));
         assertEquals("0", 1.0d, MathUtils.factorialDouble(0), 1E-14);
         assertEquals("0", 0.0d, MathUtils.factorialLog(0), 1E-14);



Mime
View raw message