Search code examples
c#algorithmfactorial

Sequence Iteration with Exponent and Factorial Produces Unexpected Results


I attempted a simple task during learning but I'm stuck and have some weird results. I have to write a simple method with 2 parameters 'x' and 'a'. Result of this method has to be sum of all xk/k! where k starts from 0 and goes to infinity, and 'a' is a parameter of accuracy.

Here how it looks

But I have no idea why when I'm putting Console.Write inside of loop, numbers are acting crazy and I have this for x = 2 and x = 6

Also when I'm trying to put my code into method and use result there is nothing happening. I have another method for mathematical factorial to calculate k!.

decimal wynik = 0;
int x = 2;
int a = 6;

for (int k = 1; k > 0; k++)
{
    if (Algorithms.Factorial(k) > 0)
    {
        wynik += Math.Round(Convert.ToDecimal(Math.Pow(x, k)) / 
                            Algorithms.Factorial(k), a);
    
        Console.WriteLine(wynik);
    }
}
    
Console.WriteLine(wynik);

and Factorial method

static public int Factorial(int n)
{
    int wynik = 1;
    
    for (int i = 1; i <= n; i++)
    {
        wynik *= i;
    }
    
    return wynik;
}

Of course I want to end with method and returning results but for practicing I'm working in Main method Thanks a lot for help!


Solution

  • Factorial grows very fast, please, look

      13! = 6227020800 > int.MaxValue
    

    that's why returning int in static public int Factorial(int n) can well lead to integer overflow and strange results. x ** k grows fast as well (though not that fast as factorial does). Let these large numbers cancel one another:

      double x = 2;
    
      double tolerance = 0.00001;
    
      double result = 1.0; // x**0 / 0! == 1 / 1 == 1
      double term = 1.0;
    
      for (int k = 1; term > tolerance; ++k) {
        // given term = (x ** (k - 1)) / (k - 1)! 
        // we can compute next term as
        term = term * x / k;
    
        result += term;
      } 
    
      // Let's have a look (in fact, you have Taylor serie for exp)
      Console.WriteLine($"actual   : {result} (+/- {tolerance:0.##############})";
      Console.WriteLine($"expected : {Math.Exp(x)}"");
    

    Outcome:

    actual   : 7.3890545668323435 (+/- 0.00001)
    expected : 7.38905609893065