-2
int n = Convert.ToInt32(Console.ReadLine());
int factorial = 1;
    
for (int i = 1; i <= n; i++)
{
    factorial *= i;    
}
Console.WriteLine(factorial);

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

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

4

3 回答 3

6

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

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

于 2012-11-04T19:49:36.463 回答
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 80000000 80000000 0

基本上乘以 2 会向左移动数字,当您乘以包含足够二的数字时,所有有效数字都将超出 32 位宽的整数(即前 6 个数字给您 4 个二:1、2、3、2*2、5、 2*3,因此将它们相乘的结果是 0x2d0,末尾有 4 个零位)。

于 2012-11-04T20:23:06.197 回答
1

如果您使用的是 .net 4.0 并且想要计算 1000 的阶乘,请尝试使用BigIntegerInt32 或 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;
        }
    }
}
于 2012-11-04T19:57:00.617 回答