精确计算大阶乘

本文关键字:阶乘 计算 | 更新日期: 2023-09-27 17:58:40

我需要计算一个非常大的阶乘,但它必须是精确的。我不能用近似法。

我想得到1000000000!,但速度很慢。到目前为止,我的表现有所提高,但仍然不够。这是我所拥有的:

        BigInteger Factor100 = BigInteger.One;
        BigInteger Factor10000 = BigInteger.One;
        Status = "Factorising";
        for (i++; i <= StartN; i++)
        {
            if (Worker.CancellationPending)
            {
                e.Cancel = true;
                break;
            }
            if (i % 10000 == 0)
            {
                Factor100 = Factor100 * i;
                Factor10000 = Factor10000 * Factor100;
                iFactorial = iFactorial * Factor10000;
                Factor100 = BigInteger.One;
                Factor10000 = BigInteger.One;
            }
            else if (i % 100 == 0)
            {
                Factor100 = Factor100 * i;
                Factor10000 = Factor10000 * Factor100;
                Factor100 = BigInteger.One;
            }
            else
            {
                Factor100 = Factor100 * i;
            }
            //iFactorial = i * iFactorial;
            if (i % Updates == 0)
            {
                Worker.ReportProgress(50, new Tuple<string, BigInteger>("Factorialising", i));
                using (StreamWriter DropWriter = File.CreateText(@FileLocation + "FactorialDropCatcher.dat"))
                {
                    DropWriter.WriteLine("N: " + i);
                    DropWriter.WriteLine("N!: " + iFactorial);
                }
            }
        }

因此,我尽量避免计算那些大得离谱的数字,直到有必要为止,保持运行的阶乘数每10000次更新一次。

我怎么能更快地计算?

精确计算大阶乘

为此,我只使用了IEnumerable<int>。产品()。这就像IEnumerable<int>。Sum(),但是乘积。对于N的阶乘,只需创建一个从1到N的范围,并取其乘积。

这是惊人的快,如果你的数字运算需求相当极端,那么修改它以使用PLINQ是很容易的!

public class FactorialExample
{
    public static BigInteger Factorial(int n)
    {
        return Enumerable.Range(2, n).Product();
    }    
}
public static class IEnumerableExtensionMethods
{
    public static BigInteger Product(this IEnumerable<int> multiplicands)
    {
        System.Numerics.BigInteger result = 1;
        foreach (int multiplier in multiplicands)
        {
            result = System.Numerics.BigInteger.Multiply(result, multiplier);
        }
        return result;
    }
}