先来月经的递归算法...
static System.Numerics.BigInteger Factorial(System.Numerics.BigInteger i)
{
if (i.IsZero || i.Sign == -1)
return System.Numerics.BigInteger.Zero;
if (i.IsOne)
return System.Numerics.BigInteger.One;
else
return i * Factorial(i - 1);
}
static void Main(string[] args)
{
if (args.Length < 1)
return;
int i;
if (int.TryParse(args[0], out i))
{
System.Numerics.BigInteger bi = i;
System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
bi = Factorial(bi);
sw.Stop();
//计算结果太长,只输出结果长度
Console.Write("结果长度:{0} 用时:{1}", bi.ToString().Length, sw.Elapsed);
}
}
Release运行...
9999! 结果长度:35656 用时:00:00:02.6131329
15000! 结果长度:56130 用时:00:00:08.6232216
15102! 结果长度:56556 用时:00:00:08.8157251
不幸由于递归堆栈溢出的问题,我测试的运行环境(x86)最大只能算到15102,15103即堆栈溢出...
于是优化一下,改为循环算法...
static System.Numerics.BigInteger Factorial(System.Numerics.BigInteger i)
{
System.Numerics.BigInteger result = 1;
while (true)
{
if (i < 2)
return result;
result *= i;
i--;
}
}
9999! 结果长度:35656 用时:00:00:00.2164311
15000! 结果长度:56130 用时:00:00:00.5164868
15102! 结果长度:56556 用时:00:00:00.5154113
效率很惊人,但还没完...
99999! 结果长度:456569 用时:00:00:36.1188483
36秒多!看来微软在匆匆推出System.Numerics又匆匆撤回后做了大量的优化...
那么999999能算吗?答案是能!结果是多少?抱歉,我这儿还没算完,跑了10多分钟了...
值得一提的是这段代码运行时内存占有并不大,很稳定...工作设置内存在11MB左右,专用工作集内存在5MB左右...即使是现在正在计算999999!,也不过12MB左右和6MB左右...
还要注意一点...System.Numerics并没有包含在C#项目的默认引用中,需要添加引用程序集...这是为什么呢?因为F#!但是...明天上午我有事要早睡,以后有空再介绍吧...