c#可以将LINQ Aggregate强制转换为double来输出阶乘,这适用于12以内的整数 &g



我想用linq填充阶乘列表。我知道了,这能撑到12。我想这是因为整数范围。但我没法重打一遍。这可以很容易地修改(重打)吗?

var listOfFactorials = from fact in Enumerable.Range(0, 171).Reverse().ToList() select new { Number = fact, Factorial = (fact == 0) ? 1d : Enumerable.Range(1, fact).Aggregate((i, j) => (i * j))};

我想用阶乘填充这个列表直到数字170。我不需要它做任何事情,只是为了好玩:)

必须使用BigInteger:

var listOfFactorials = from fact in Enumerable.Range(0, 200).Reverse().ToList()
select new 
{ 
Number = fact, 
Factorial = (fact == 0) ? BigInteger.One : Enumerable.Range(1, fact)
           .Select( i => new BigInteger(i))
           .Aggregate((i, j) => (i * j))
};

您不需要double-它只给您15位精度以换取更大的范围。您想使用longBigInteger

您可以在调用Aggregate之前转换从Range返回的整数:

Enumerable.Range(1, fact)
.Select(i => new BigInteger(i))
.Aggregate((i, j) => (i * j))};

或者使用更详细的Aggregate版本,分别指定类型:

Enumerable.Range(1, fact)
.Aggregate<int, BigInteger>(new BigInteger(1), (i, j) => (i * j))

注意Long会在67!溢出,而BigInteger理论上是无界的

请注意,您的Aggregate不是很有效,因为它每次都从1重新计算到n,如果您从1开始,您只能对每个后续值执行一次倍数:

var listOfFactorials = Enumerable.Range(1, 170)
.Aggregate(new[] { new { Number = 0, Factorial = BigInteger.One } }.ToList(),
(ans, n) => { ans.Add(new { Number = n, Factorial = ans.Last().Factorial * n }); return ans; })
.AsEnumerable()
.Reverse();

由于序列是用0值初始化的,所以少一个值的范围必须从1开始。

一个更简单(可能更容易理解)的方法是使用for循环:

var ans = new[] { new { Number = 0, Factorial = BigInteger.One } }.ToList();
var Factorial = BigInteger.One;
for (int Number = 1; Number < 171; ++Number) {
Factorial *= Number;
ans.Add(new { Number, Factorial });
}
ans.Reverse();

相关内容

  • 没有找到相关文章

最新更新