为什么计算相对较小数字(34+)的阶乘返回0

时间:2012-11-04 19:47:59

标签: c# console-application

int n = Convert.ToInt32(Console.ReadLine());
int factorial = 1;

for (int i = 1; i <= n; i++)
{
    factorial *= i;    
}
Console.WriteLine(factorial);

此代码在控制台应用程序中运行,但当数字大于34时,应用程序返回0.

为什么返回0以及如何计算大数的阶乘?

3 个答案:

答案 0 :(得分:6)

您将超出变量可以存储的范围。这实际上是一个因子,它比指数增长得更快。尝试使用ulong(最大值2 ^ 64 = 18,446,744,073,709,551,615)而不是int(最大值2 ^ 31 = 2,147,483,647) - ulong p = 1 - 这应该会让你更进一步。

如果你需要更进一步,.NET 4及更高版本BigInteger可以存储任意大数字。

答案 1 :(得分:3)

由于大多数编程语言中处理整数溢出的方式,你得到0。如果在循环中输出每个计算的结果(使用HEX表示),您可以很容易地看到会发生什么:

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);

对于n = 34,结果如下:

1 2 6 18 78 2D0 13b0 ... 2c000000 8000 8000 0

基本上乘以2个左移数字,当你乘以包含足够两个数量的数字时,所有有效数字都将超出32位宽的整数(即前6个数字给你4个两个:1,2,3,2 * 2 ,5,2 * 3,因此乘以它们的结果是0x2d0,最后有4个零位。)

答案 2 :(得分:1)

如果您使用.net 4.0并且想要计算1000的阶乘,那么尝试使用BigInteger而不是Int32或Int64甚至UInt64。你的问题陈述“不起作用”对我来说还不足以给予一些好的服从。 您的代码将类似于:

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;
        }
    }
}