For my curiosity I am writing a code to find the factorial of large number eg:25. For that I wrote the below code. I use BigInteger as it can store value of any length as define per memory.
int a = 13;
BigInteger factorial1 = a == 0 ? 1 : Enumerable.Range(1, a).Aggregate((i, j) => i * j); // Aggregate function not working properly after 12 factorial
Console.WriteLine(factorial1);
But surprisingly, I don't get the correct answer. I tried for smaller number upto 12 factorial and it gives correct answer but for 13 and beyond, the answer is wrong.
I have tried this very simple code which gives the correct answer.
BigInteger factorial3 = 1;
while (n > 0)
{
factorial3 = factorial3 * n;
--n;
}
Console.WriteLine(factorial3);
But the problem here is that BigInteger is immutable. So the above code will have a large memory foot print which is not desirable.
You should specify starting aggregation value, it should be BigInteger.One
:
BigInteger factorial1 = a == 0 ? 1 : Enumerable
.Range(1, a)
.Aggregate(BigInteger.One, (i, j) => i * j);
otherwise for .Aggregate((i, j) => i * j)
the result will be of type int
(since both i
and j
are int
) and only then (after integer overflow , 13. = 6227020800 > int.MaxValue = 2147483647
) it will be cast to BigInteger
.
Enumerable.Range produces int
s, not BigInteger
s. Enumerable.Range(1, a).Aggregate((i, j) => i * j);
uses Int32
throughout and ends up overflowing after 13.
To avoid overflow you need to convert those integers to BigInteger before processing them:
var n=Enumerable.Range(1, 13).Select(i=>(BigInteger)i)
.Aggregate((i, j) => i * j);
This produces 6227020800
Another option is to create your own Range
method that creates BigInteger
values:
public static IEnumerable<BigInteger> BigRange(BigInteger start,int count)
{
for(var i=start;i<start+count;i++)
{
yield return i;
}
}
...
var n=BigRange(1, 13).Aggregate((i, j) => i * j);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.