英文:
C# can cast LINQ Aggregate to double to output factorial, this works for integer up to 12
问题
Sure, here's the translation of the code part:
我想使用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))};
Is there anything else you would like to know or translate?
英文:
I want to fill the list with factorials using linq.
I got this, this works up to 12. I assume it's because of the integer range. But I couldn't retype it to double. Can this be easily modified (retyped)?
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))};
I want to have the list filled with factorials up to the number 170.
I don't need it for anything, just playing for fun
答案1
得分: 0
You don't want double
- it only gives you 15 digits of precision in exchange for the larger range. You want to use either long
or BigInteger
.
You can either convert the integers returned from Range
before calling Aggregate
:
Enumerable.Range(1, fact)
.Select(i => new BigInteger(i))
.Aggregate((i, j) => (i * j))
or use the more verbose version of Aggregate
where you specify the types separately:
Enumerable.Range(1, fact)
.Aggregate<int, BigInteger>(new BigInteger(1), (i, j) => (i * j))
Note that long
will overflow at 67!
while BigInteger
is unbounded in theory.
英文:
You don't want double
- it only gives you 15 digits of precision in exchange for the larger range. You want to use either long
or BigInteger
.
You can either convert the integers returned from Range
before calling Aggregate
:
Enumerable.Range(1, fact)
.Select(i => new BigInteger(i))
.Aggregate((i, j) => (i * j))};
or use the more verbose version of Aggregate
where you specify the types separately:
Enumerable.Range(1, fact)
.Aggregate<int, BigInteger>(new BigInteger(1), (i, j) => (i * j))
Note that Long will overflow at 67!
while BigInteger
is unbounded in theory
答案2
得分: 0
你必须使用 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))
};
英文:
You have to use 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))
};
答案3
得分: 0
请注意,您的“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();
希望这有帮助。
英文:
Note that your Aggregate
is not very efficient since it recalculates from 1 to n every time, if you start with 1, you can just do one multiple for each subsequent value:
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();
Since the sequence is initialized with the 0
value, the range must start at 1
for one fewer values.
A simpler (and probably more understandable) method would be to just use a for
loop:
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();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论