简体   繁体   中英

Dividing two Ulong integers outputs wrong result

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


这是公式


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.

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 .

you should use a System.Numerics.BigInteger for this. (add System.Numerics as reference in your project).

private static BigInteger factorial(int n)
{
     BigInteger fact = 1;
     for (int i = 1; i <= n; i++)
     {
        fact *= i;
     }
     return fact;
 }

 // output: 9694845

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM