You can actually simplify this quite a bit. But first, what's wrong with your existing code is that you're not computing i!
correctly. The sequence you're actually computing right now is:
X^N / N + X^N / (2 * N) + X^N / (3 * N) + ... + X^N / ((N - 1) * N)
A few things:
- The loop has an off-by-one issue
- The numerator is raised to the wrong power
- The denominator of these needs to be i!
Factorials are defined through a simple recurrence relation:
i! = i * (i - 1)!
and 0! = 1
Or, in other words, the product of the first i
consecutive natural numbers. So one way to correct this is by creating a method called Factorial:
static long Factorial(int i)
{
long product = 1;
while (i > 0) {
product *= i;
--i;
}
return product;
}
Then you can fix your loop this way:
for (int i = 1; i < N; i++)
{
sum += Math.Pow(X, i) / Factorial(i);
}
However, we're redoing a lot of work every iteration of the loop that we don't need to do. This is where the simplification comes in. The general formula for the i
'th term is this:
C[i] = X^i / i!
But we can also write this in terms of the term that came before it:
C[i] = C[i-1] * X / i
So we can rewrite the loop like this:
double lastTerm = 1;
for (int i = 1; i <= N; ++i)
{
// Cast to double here or, probably better, make X a double in the first place.
lastTerm *= (double) X / i;
sum += lastTerm;
}
This has several advantages:
- It'll generally be faster since we're doing less work each iteration (
Math.Pow
computes arbitrary powers, so it's a bit slower than just multiplying).
- It'll be less prone to numerical issues. Factorials get really big really fast. In fact, 21! is already too big to store in a
long
so if your N
is bigger than that, everything will break.