ABSTRACT

Both of the above definitions incorporate the instance 0! = 1. Implementing n! in C# is a bit tricky since even small integer values, such as

n > 12, will quickly throw a numerical overflow exception. Even calculating n! by recursion works well only for small values of n. As n increases in value, calculating

{

double Result; if (number < 0) {

throw new Exception("Input value must be > 0"); } if (number == 0.0) Result = 1; //0! = 1 else //Recursively call the Factorial function Result = (number * Factorial(number - 1)); return Result;

}

A much better approach to calculating n! is to first calculate the natural logarithm of n! and then take the natural exponent of the result so that we finally end up with the more efficient expression n! = exp(lnn!). The following C# code implements this improved method for calculating n!. Now one is able to calculate n! to as high as 170!≈ 7.25741561530799E+306 before a numerical overflow exception is thrown. Unfortunately, because of the physical hardware limitations for handling very large numbers, computers can only provide approximate results for calculating factorials for n > 23. In addition, this new method for calculating n! runs much faster if you just use simple table lookups for n <= 23 and so using the formula n! = exp(lnn!) is recommended only for values n > 23. In any event, the C# code for calculating n! using n! = exp(lnn!) with the requirement of n ≤ 170 is given below. private static readonly double[] factorialLookup = {

1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0, 362880.0, 3628800.0, 39916800.0, 479001600.0, 6227020800.0, 87178291200.0, 1307674368000.0, 20922789888000.0, 355687428096000.0, 6402373705728000.0, 121645100408832000.0, 2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0,

//For n > 24, it calculates n! = exp(Ln(n!)) public static double Factorial(int n) {

if (n < 0) {

throw new Exception("Input value must be a > 0"); } else if (n < 24) {

return factorialLookup[n]; } else {

return Math.Floor(System.Math.Exp(FactorialLn(n))+0.5); }

}

public static double FactorialLn(int n) {

if (n < 0) {

throw new Exception("Input value must be > 0"); } else {

return GammaLn(n+1.0); }

}

static void Main(string[] args) //Testing of n! {

try {

Console.WriteLine("Factorial(5) = {0}", Factorial(5)); Console.WriteLine("Factorial(-5) = {0}", Factorial(-5)); Console.ReadLine();

} catch(Exception ex) {

Console.WriteLine("Fatal error: " + ex.Message); }

} OUTPUT: Factorial(5) = 120 Factorial(-5) = Fatal error: Input value must be > 0

14.3 Combinations and Permutations Combinatorics is the branch of mathematics studying the enumeration, combination, and permutation of sets of elements and the mathematical relations that characterize their properties. Mathematicians sometimes use the term combinatorics to refer to a larger subset of discrete mathematics that includes graph theory. In addition to applications in pure and applied mathematics, engineering and the physical sciences, combinatorial mathematics has also many useful applications in computer science, particularly in the study of data structures and network design and analysis. More recently, concepts involving combinations and permutations of sets of elements have also found many important applications in the area of software testing.