【发布时间】:2016-02-24 06:45:17
【问题描述】:
我在C# 中使用BigInteger 与阶乘函数相关。该程序具有闪电般的快速计算 5000!,但在 10000! 处有溢出错误。根据wolfram alpha,10000!大约是
10000! = 2.8 x 10^35659
据我从this post 得知,BigInteger 存储在int[] 数组中。如果我正确解释 int 类型,它使用 4 个字节,这意味着 10000!使用大约4 x log10(2.8 x 10^35659) = 142636 字节,其中我使用log10(n)(以10 为底的日志)作为n 位数的近似值。这只有 143 MB,但我仍然得到堆栈溢出异常。为什么会这样?
using System;
using System.Numerics;
class Program
{
static void Main()
{
BigInteger hugeFactorial = Calculations.Factorial(5000);
}
}
class Calculations
{
public static BigInteger Factorial(int n)
{
if (n == 1) return n;
else return n*Factorial(n - 1);
}
}
【问题讨论】:
-
堆栈溢出异常吧?
-
@IvanStoev 是的,堆栈溢出异常。它说:“发生了'System.StackOverflowException'类型的未处理异常”让我更正我的帖子。
-
你刚刚回答了你的问题。您是否在异常中看到“BigInteger”一词?你看到“堆栈”这个词了吗?哪个代码在使用堆栈?
-
x64 抖动出错,该方法需要 208 字节的堆栈空间。 5000 x 208 == kaboom,堆栈大小为 1MB。您必须编写一个迭代版本,而不是您现在拥有的递归版本。一个 for(;;) 循环。
-
我查看了机器码。 208 特定于 RyuJIT,VS2015 包含的 x64 抖动。它使用 AVX 指令,使其更需要堆栈。否则一个细节,代码可以通过让参数足够大来任意轰炸。
标签: c# stack-overflow biginteger