changeset 360:a694700f71d8

Factorial: return double (int not big enough for many popular values)
author Chris Cannam <c.cannam@qmul.ac.uk>
date Wed, 16 Oct 2013 16:44:14 +0100
parents 0ea56b09577e
children 3a6f9b27fb36
files maths/MathUtilities.cpp maths/MathUtilities.h tests/TestMathUtilities.cpp
diffstat 3 files changed, 12 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/maths/MathUtilities.cpp	Wed Oct 16 13:29:00 2013 +0100
+++ b/maths/MathUtilities.cpp	Wed Oct 16 16:44:14 2013 +0100
@@ -379,11 +379,11 @@
     else return n1;
 }
 
-int
+double
 MathUtilities::factorial(int x)
 {
     if (x < 0) return 0;
-    int f = 1;
+    double f = 1;
     for (int i = 1; i <= x; ++i) {
 	f = f * i;
     }
--- a/maths/MathUtilities.h	Wed Oct 16 13:29:00 2013 +0100
+++ b/maths/MathUtilities.h	Wed Oct 16 16:44:14 2013 +0100
@@ -65,7 +65,7 @@
     static int previousPowerOfTwo(int x); // e.g. 1300 -> 1024, 2048 -> 2048
     static int nearestPowerOfTwo(int x); // e.g. 1300 -> 1024, 12 -> 16 (not 8)
 
-    static int factorial(int x);
+    static double factorial(int x); // returns double in case it is large
 
     static int gcd(int a, int b);
 };
--- a/tests/TestMathUtilities.cpp	Wed Oct 16 13:29:00 2013 +0100
+++ b/tests/TestMathUtilities.cpp	Wed Oct 16 16:44:14 2013 +0100
@@ -125,12 +125,15 @@
 
 BOOST_AUTO_TEST_CASE(factorial)
 {
-    BOOST_CHECK_EQUAL(MathUtilities::factorial(-10), 0);
-    BOOST_CHECK_EQUAL(MathUtilities::factorial(0), 1);
-    BOOST_CHECK_EQUAL(MathUtilities::factorial(1), 1);
-    BOOST_CHECK_EQUAL(MathUtilities::factorial(2), 2);
-    BOOST_CHECK_EQUAL(MathUtilities::factorial(3), 6);
-    BOOST_CHECK_EQUAL(MathUtilities::factorial(4), 24);
+    BOOST_CHECK_EQUAL(MathUtilities::factorial(-10), 0.0);
+    BOOST_CHECK_EQUAL(MathUtilities::factorial(0), 1.0);
+    BOOST_CHECK_EQUAL(MathUtilities::factorial(1), 1.0);
+    BOOST_CHECK_EQUAL(MathUtilities::factorial(2), 2.0);
+    BOOST_CHECK_EQUAL(MathUtilities::factorial(3), 6.0);
+    BOOST_CHECK_EQUAL(MathUtilities::factorial(4), 24.0);
+
+    // Too big for an int, hence double return value from factorial
+    BOOST_CHECK_EQUAL(MathUtilities::factorial(20), 2432902008176640000.0);
 }
 
 BOOST_AUTO_TEST_CASE(gcd)