【问题标题】:Why does computing factorial of relatively small numbers (34+) return 0?为什么计算相对较小数字(34+)的阶乘返回 0?
【发布时间】:2012-10-24 16:54:24
【问题描述】:
int n = Convert.ToInt32(Console.ReadLine());
int factorial = 1;
    
for (int i = 1; i <= n; i++)
{
    factorial *= i;    
}
Console.WriteLine(factorial);

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

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

【问题讨论】:

    标签: c# console-application


    【解决方案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;
            }
        }
    }
    

    【讨论】:

    • "BigInteger" 未在代码和编译器中定义给我错误!
    • 我已将其更改为完整的控制台应用程序 Snnipet
    • 我是初学者 .sorry(: 编译器给出错误。空间名称中不存在“数字”
    • 它应该是 System.Numerics 命名空间。再检查一次。在上面的示例中,此命名空间拼写正确。我已经在我的机器上运行了该代码,它产生了正确的结果
    【解决方案2】:

    由于大多数编程语言处理整数溢出的方式,您得到 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 个零位)。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • @user169654 是的,正如代码在 cmets 中指出的那样,BigInteger 可能是要走的路。您必须在项目中添加对System.Numerics 的引用。
      • +1... 关于阶乘的另一个有趣事实是,由于产品的 2^32 部分,它将开始返回 0。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      • 2021-05-29
      相关资源
      最近更新 更多