Search code examples
c#mathfactorialcatalan

Dividing two Ulong integers outputs wrong result


I am writing a program for Catalan number. So here is the formula for that:


This is the formula


I decided to use the middle part of the formula, because the other parts are too abstract for my knowledge (maybe I slept too much in math classes). Actually my program works fine for n = 0;,n = 5;, n = 10; But if I enter n = 15; - here comes the boom - the output is 2 when it should be 9694845. So here is my child:

using System;
namespace _8_Numbers_of_Catalan
{
    class CatalanNumbers
    {
        static void Main()
        {
            Console.Write("n: ");
            int n = int.Parse(Console.ReadLine());
            Console.WriteLine("Catalan({0})", n);
            //calculating the Catan number from the formula 
            // Catan(n) = [(2*n)!]/[(n+1)! * n!]
            Console.WriteLine((factorial(2 * n)) / (factorial(n + 1) * factorial(n)));
        }//finding the factorial
        private static ulong factorial(int n)
        {
            ulong fact = 1;
            for (int i = 1; i <= n; i++)
            {
                fact *= (ulong)i;
            }
            return fact;
        }
    }
}

Thank you in advance for understanding me if there is something obviously wrong. I am new in programming.


Solution

  • That is because you are performing calculation of these using integer variables that can contain at most 64 bits.

    Your call to factorial(15 * 2) is 30! which would result in a value of

    265,252,859,812,191,058,636,308,480,000,000
    

    Much more than fits in a 64 bit integer variable:

    18,446,744,073,709,551,615 (0xFFFFFFFFFFFFFFFF).
    

    The options you have are to use a System.Numerics.BigInteger type (slow) or a double (up to a maximum value of 1.7976931348623157E+308). Which means you will loose some precision, that may or may not be relevant.

    Another option you have is to use an algorithm to approximate the value of large factorials using an asymptotic approximation such as the Schönhage–Strassen algorithm used by Mathematica.

    You may also want to check out some existing online resources for calculation of big factorials in .NET

    As a last but not least option (and I have not thoroughly checked) it seems likely to me that specific algorithms exists that allow you to calculate (or approximate to a sufficient accuracy and precision) a Catalan number.