Changed factorial methods to return 1 for argument = 0.

Pr #31687
Reported by: Fredrik Norin


git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@141473 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Phil Steitz 2004-10-14 04:01:04 +00:00
parent 73aa4c97d1
commit 20eb63732c
2 changed files with 16 additions and 12 deletions

View File

@ -19,7 +19,7 @@ package org.apache.commons.math.util;
/** /**
* Some useful additions to the built-in functions in {@link Math}. * Some useful additions to the built-in functions in {@link Math}.
* *
* @version $Revision: 1.19 $ $Date: 2004/06/23 16:26:16 $ * @version $Revision: 1.20 $ $Date: 2004/10/14 04:01:04 $
*/ */
public final class MathUtils { public final class MathUtils {
@ -348,7 +348,7 @@ public final class MathUtils {
* *
* <p> * <p>
* <Strong>Preconditions</strong>:<ul> * <Strong>Preconditions</strong>:<ul>
* <li> <code>n > 0</code> (otherwise * <li> <code>n >= 0</code> (otherwise
* <code>IllegalArgumentException</code> is thrown)</li> * <code>IllegalArgumentException</code> is thrown)</li>
* <li> The result is small enough to fit into a <code>long</code>. The * <li> The result is small enough to fit into a <code>long</code>. The
* largest value of <code>n</code> for which <code>n!</code> * largest value of <code>n</code> for which <code>n!</code>
@ -362,6 +362,7 @@ public final class MathUtils {
* @return <code>n!</code> * @return <code>n!</code>
* @throws ArithmeticException if the result is too large to be represented * @throws ArithmeticException if the result is too large to be represented
* by a long integer. * by a long integer.
* @throws IllegalArgumentException if n < 0
*/ */
public static long factorial(final int n) { public static long factorial(final int n) {
long result = Math.round(factorialDouble(n)); long result = Math.round(factorialDouble(n));
@ -380,7 +381,7 @@ public final class MathUtils {
* *
* <p> * <p>
* <Strong>Preconditions</strong>:<ul> * <Strong>Preconditions</strong>:<ul>
* <li> <code>n > 0</code> (otherwise * <li> <code>n >= 0</code> (otherwise
* <code>IllegalArgumentException</code> is thrown)</li> * <code>IllegalArgumentException</code> is thrown)</li>
* <li> The result is small enough to fit into a <code>double</code>. The * <li> The result is small enough to fit into a <code>double</code>. The
* largest value of <code>n</code> for which <code>n!</code> * largest value of <code>n</code> for which <code>n!</code>
@ -391,10 +392,11 @@ public final class MathUtils {
* *
* @param n argument * @param n argument
* @return <code>n!</code> * @return <code>n!</code>
* @throws IllegalArgumentException if n < 0
*/ */
public static double factorialDouble(final int n) { public static double factorialDouble(final int n) {
if (n <= 0) { if (n < 0) {
throw new IllegalArgumentException("must have n > 0 for n!"); throw new IllegalArgumentException("must have n >= 0 for n!");
} }
return Math.floor(Math.exp(factorialLog(n)) + 0.5); return Math.floor(Math.exp(factorialLog(n)) + 0.5);
} }
@ -403,7 +405,7 @@ public final class MathUtils {
* Returns the natural logarithm of n!. * Returns the natural logarithm of n!.
* <p> * <p>
* <Strong>Preconditions</strong>:<ul> * <Strong>Preconditions</strong>:<ul>
* <li> <code>n > 0</code> (otherwise * <li> <code>n >= 0</code> (otherwise
* <code>IllegalArgumentException</code> is thrown)</li> * <code>IllegalArgumentException</code> is thrown)</li>
* </ul> * </ul>
* *
@ -412,7 +414,7 @@ public final class MathUtils {
* @throws IllegalArgumentException if preconditions are not met. * @throws IllegalArgumentException if preconditions are not met.
*/ */
public static double factorialLog(final int n) { public static double factorialLog(final int n) {
if (n <= 0) { if (n < 0) {
throw new IllegalArgumentException("must have n > 0 for n!"); throw new IllegalArgumentException("must have n > 0 for n!");
} }
double logSum = 0; double logSum = 0;

View File

@ -22,7 +22,7 @@ import junit.framework.TestSuite;
/** /**
* Test cases for the MathUtils class. * Test cases for the MathUtils class.
* *
* @version $Revision: 1.14 $ $Date: 2004/06/17 21:31:00 $ * @version $Revision: 1.15 $ $Date: 2004/10/14 04:01:04 $
*/ */
public final class MathUtilsTest extends TestCase { public final class MathUtilsTest extends TestCase {
@ -120,23 +120,26 @@ public final class MathUtilsTest extends TestCase {
assertEquals(i + "! ",Math.log((double)factorial(i)), assertEquals(i + "! ",Math.log((double)factorial(i)),
MathUtils.factorialLog(i),10E-12); 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);
} }
public void testFactorialFail() { public void testFactorialFail() {
try { try {
long x = MathUtils.factorial(0); long x = MathUtils.factorial(-1);
fail ("expecting IllegalArgumentException"); fail ("expecting IllegalArgumentException");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
; ;
} }
try { try {
double x = MathUtils.factorialDouble(0); double x = MathUtils.factorialDouble(-1);
fail ("expecting IllegalArgumentException"); fail ("expecting IllegalArgumentException");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
; ;
} }
try { try {
double x = MathUtils.factorialLog(0); double x = MathUtils.factorialLog(-1);
fail ("expecting IllegalArgumentException"); fail ("expecting IllegalArgumentException");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
; ;
@ -149,7 +152,6 @@ public final class MathUtilsTest extends TestCase {
} }
assertTrue("expecting infinite factorial value", assertTrue("expecting infinite factorial value",
Double.isInfinite(MathUtils.factorialDouble(171))); Double.isInfinite(MathUtils.factorialDouble(171)));
} }