准确计算大因子

时间:2016-07-26 09:17:12

标签: c# biginteger factorial

我需要计算一个非常大的因子,但它必须是精确的。我无法使用近似值。

我想获得1,000,000,000!但它很慢。到目前为止,我的性能有所改善,但仍然不够。这就是我所拥有的:

        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);
                }
            }
        }

所以,我试图远离计算疯狂的大数,直到它变得必要,保持运行的因子数每10,000只更新一次。

我怎么能更快地计算出来?

1 个答案:

答案 0 :(得分:0)

为此,我只使用IEnumerable&lt; int&gt; .Product()的扩展方法。它就像IEnumerable&lt; int&gt; .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;
    }
}