For loop in c# vs For loop in python

Question:

I was writing a method that would calculate the value of e^x. The way I implemented this in python was as follows.

import math

def exp(x):
    return sum([
        x**n/math.factorial(n)
        for n in range(0, 100)
    ])

This would return the value of e^x very well. But when I tried to implement the same method in c#, it didn’t output the same value as it did in python. The following was the implementation in c#.

static double exp(int x)
{
    double FinalAnswer = 0;
    for (int j = 0; j <= 100; j++)
    {
        FinalAnswer += (Math.Pow(x, j))/Factorial(j);
    }
    return FinalAnswer;
}

The output for this code was an infinity symbol at first. To resolve this I just reduced the number of times the loop ran. The output of the code in c# where the loop only ran 10 times was pretty close to the output in python where the loop ran 100 times. My question is that what is going on between the two loops in different programming languages. At first I thought that the expression that I was using in my method to calculate e^x was converging quickly. But how does a loop that runs 10 times produce an output that matches the output of a loop that runs 100 times.

Also, When I increased the for loop in c# to 20 and 30, the values of e^x for x > 3 were way off. Could someone explain what is going on here?

Asked By: Seeker

||

Answers:

What you’re likely running into here is integer overflow with the C# version of the Factorial function (at least your implementation of it, or wherever its coming from).

In C#, an int is a numerical type stored in 32 bits of memory, which means it’s bounded by -2^31 <= n <= 2^31 - 1 which is around +/- 2.1 billion. You could try using a long type, which is a 64 bit numerical type, however for even larger upper bounds in your for loop, like getting close to 100, you’re going to overflow long as well.

When you run the Factorial function in C#, it starts off normally for the first little while, however if you keep going, you’ll see that it all of a sudden jumps into negative numbers, and if you keep going even further than that, it’ll get to 0 and stop changing. You’re seeing the output of infinity due to division by 0, and C# has a way of handling that with doubles; that being to just return double.PositiveInfinity.

The reason why this doesn’t happen in python is that it uses a variable number of bits to store its numerical values.

Added note: What you might also want to try is using a Factorial function that works with the double type instead of int or long, however by doing this, you’ll lose precision on what the exact value is, but you get more range as the magnitude of the number you can store is larger

Further Note: As mentioned in the comments, C# has a type called BigInteger which is designed to handle huge numbers like the values you would expect from large inputs to a Factorial function. You can find a reference to the BigInteger docs here


What you can do is calculate each component of the factorial function separately with the power you’re using. Here’s what I mean:

public decimal Exp(decimal power, int accuracy = 100)
{
    decimal runningTotal = 1;
    decimal finalValue = 1;
    for (int i = 1; i <= accuracy; i++)
    {
        runningTotal *= power/i;
        finalValue += runningTotal;
    }
    return finalValue;
}
Answered By: MoonMist
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.