C# 精确计算大阶乘

C# 精确计算大阶乘,c#,biginteger,factorial,C#,Biginteger,Factorial,我需要计算一个非常大的阶乘,但是它必须是精确的。我不能用近似值 我想得到100000000!,但是速度很慢。到目前为止,我已经提高了一点性能,但仍然不够。以下是我所拥有的: BigInteger Factor100 = BigInteger.One; BigInteger Factor10000 = BigInteger.One; Status = "Factorising"; for (i++; i <= StartN; i

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

我想得到100000000!,但是速度很慢。到目前为止,我已经提高了一点性能,但仍然不够。以下是我所拥有的:

        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);
                }
            }
        }
biginger Factor100=biginger.1;
BigInteger Factor10000=BigInteger.1;
Status=“保理”;

对于(i++;i对于这一点,我只使用IEnumerable.Product()的扩展方法。它类似于IEnumerable.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;
    }
}
公共类FactorialExample
{
公共静态双整数阶乘(int n)
{
返回可枚举的.Range(2,n).Product();
}    
}
公共静态类IEnumerableExtensionMethods
{
公共静态BigInteger乘积(此IEnumerable被乘数)
{
System.Numerics.BigInteger结果=1;
foreach(被乘数中的整数乘数)
{
结果=System.Numerics.BigInteger.乘法(结果,乘法器);
}
返回结果;
}
}

为此,我只对IEnumerable.Product()使用一个扩展方法。它类似于IEnumerable.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;
    }
}
公共类FactorialExample
{
公共静态双整数阶乘(int n)
{
返回可枚举的.Range(2,n).Product();
}    
}
公共静态类IEnumerableExtensionMethods
{
公共静态BigInteger乘积(此IEnumerable被乘数)
{
System.Numerics.BigInteger结果=1;
foreach(被乘数中的整数乘数)
{
结果=System.Numerics.BigInteger.乘法(结果,乘法器);
}
返回结果;
}
}

这是一个数学问题,而不是编程问题,你没有解释你做了什么(可能是预先计算的阶乘?)。显示进度很昂贵,你已经减少了。
100000000!=9.90462…38144
8565705522
数字)只有
24999998
尾随的零。如果删除尾随的零,您将拥有(最多)
8565705522-24999998==8315705524
-3%的改进为什么您想要精确的阶乘值?斯特林公式提供了一个合理的近似值:@Sinatr我只是有一种方法可以为它提供上次保存的值,这样我就可以给它一个先前保存到文本文件中的I和iFactorial的值se,这一点它们都等于1。DmitryBychenko我需要它是精确的数字,如OP中所述。原因是我计划用它进行的计算取决于它是精确的数字。什么样的计算?也许解释这个问题会帮助你得到优化的公式,而不需要执行那个多次迭代。您似乎高估了精度。这是一个数学问题,而不是编程问题,您没有解释您所做的工作(可能是预先计算的阶乘?)。显示进度很昂贵,您已经降低了进度。
100000000!=9.90462…38144
8565705522
digits)只有
24999998
尾随的零。如果删除尾随的零,您将拥有(最多)
8565705522-24999998==8315705524
-3%的改进为什么您想要精确的阶乘值?斯特林公式提供了一个合理的近似值:@Sinatr我只是有一种方法可以为它提供上次保存的值,这样我就可以给它一个先前保存到文本文件中的I和iFactorial的值se,这一点它们都等于1。DmitryBychenko我需要它是精确的数字,如OP中所述。原因是我计划用它进行的计算取决于它是精确的数字。什么样的计算?也许解释这个问题会帮助你得到优化的公式,而不需要执行那个多次迭代。您似乎高估了准确性。