Looking at your code, it is no wonder that you will run out of memory quite fast. Your method divideFactorials
calls the method factorial and uses as argument the difference "numerator-denominator". That difference is very likely going to be very large according to your code and you will be stuck in a very long loop in your factorial method.
If it is really just about finding nCk (which I assume because your comment in your code), just use:
public static long GetnCk(long n, long k)
{
long bufferNum = 1;
long bufferDenom = 1;
for(long i = n; i > Math.Abs(n-k); i--)
{
bufferNum *= i;
}
for(long i = k; i => 1; i--)
{
bufferDenom *= i;
}
return (long)(bufferNom/bufferDenom);
}
Of course using this method you will run out of range very fast, because a long does not actually support very long numbers, so n and k have to be smaller than 20.
Supposing that you actually work with very large numbers you could use doubles instead of longs, as the powers become more and more significant.
Edit:
If you use large numbers you could also use Stirling's Formula:
As n becomes large ln(n!) -> n*ln(n) - n.
Putting this into code:
public static double GetnCk(long n, long k)
{
double buffern = n*Math.Log(n) - n;
double bufferk = k*Math.Log(k) - k;
double bufferkn = Math.Abs(n-k)*Math.Log(Math.Abs(n-k)) - Math.Abs(n-k);
return Math.Exp(buffern)/(Math.Exp(bufferk)*Math.Exp(bufferkn));
}
I only propose this answer, as you said language independent, the C# code is just used to demonstrate it. Since you need to use large numbers for n and k for this to work, i propose this as a general way for finding the binomial coefficient for large combinations.
For cases were n and k are both smaller than around 200-300, you should use the answer Victor Mukherjee proposed, as it is exact.
Edit2:
Edited my first code.
if (n > 20) throw new OverflowException();
– Nerine