LINQ Aggregate函数计算13阶乘及以上结果异常求助
为什么用LINQ Aggregate计算13及以上阶乘会出错?
你第一段代码的问题出在类型推导上:Enumerable.Range(1, a)生成的是int类型的序列,当调用不带初始值的Aggregate时,方法会默认用序列的第一个元素(int类型)作为累积初始值,后续所有乘法运算都在int类型上执行。
12的阶乘是479001600,还在int的取值范围(-2147483648到2147483647)内,所以计算正确;但13的阶乘是6227020800,远超int最大值,这里会发生整数溢出(默认情况下C#不会抛出溢出异常,直接返回截断后的错误值),最后把错误的int值转成BigInteger,结果自然不对。
修正方案
给Aggregate指定一个BigInteger类型的初始值,强制整个累积过程用BigInteger运算,就能避免溢出问题:
int a = 13; BigInteger factorial1 = a == 0 ? BigInteger.One : Enumerable.Range(1, a).Aggregate(BigInteger.One, (i, j) => i * j); Console.WriteLine(factorial1);
关于内存占用的疑问
你提到BigInteger是不可变类型,循环写法内存占用大,但其实两种写法的内存开销差异极小——因为每次BigInteger乘法都会创建新实例,不管是循环还是LINQ的Aggregate,本质都是相同的累积过程。修正后的LINQ写法既简洁,又能保证计算正确,完全可以替代循环版本。
内容的提问来源于stack exchange,提问作者silver spark
相关产品推荐
相关产品推荐

