Why computing factorial of realtively small numbers (34+) returns 0

旧巷老猫 提交于 2019-11-27 16:32:16

You're going out of range of what the variable can store. That's effectively a factorial, which grows faster than the exponential. Try using ulong (max value 2^64 = 18,446,744,073,709,551,615) instead of int (max value 2^31 = 2,147,483,647) - ulong p = 1 - that should get you a bit further.

If you need to go even further, .NET 4 and up has BigInteger, which can store arbitrarily large numbers.

You are getting 0 because of the way integer overflow handled in most programming languages. You can easily see what happens if you output results of each computation in a loop (using HEX representation):

int n = Convert.ToInt32(Console.ReadLine());
int factorial = 1;
for (int i = 1; i <= n; i++)
{
  factorial *= i;
  Console.WriteLine("{0:x}", factorial);
}
Console.WriteLine(factorial);

For n = 34 result look like:

1 2 6 18 78 2d0 13b0 ... 2c000000 80000000 80000000 0

Basically multiplying by 2 shifts numbers left and when you multiplied numberer containing enough twos all significant digits will fall out of integer which is 32 bits wide (i.e. first 6 numbers give you 4 twos : 1, 2, 3, 2*2, 5, 2*3, so result of multipying them is 0x2d0 with 4 zero bits at the end).

If you are using .net 4.0 and want to calculate factorial of 1000, then try to use BigInteger instead of Int32 or Int64 or even UInt64. Your problem statement "doesn't work" is not quite sufficient for me to give some good subjection. Your code will look something like:

using System;
using System.Numerics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            int factorial = Convert.ToInt32(Console.ReadLine());

            var result = CalculateFactorial(factorial);

            Console.WriteLine(result);
            Console.ReadLine();
        }

        private static BigInteger CalculateFactorial(int value)
        {
            BigInteger result = new BigInteger(1);
            for (int i = 1; i <= value; i++)
            {
                result *= i;
            }
            return result;
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!