C# 精确计算大阶乘
我需要计算一个非常大的阶乘,但是它必须是精确的。我不能用近似值 我想得到100000000!,但是速度很慢。到目前为止,我已经提高了一点性能,但仍然不够。以下是我所拥有的:C# 精确计算大阶乘,c#,biginteger,factorial,C#,Biginteger,Factorial,我需要计算一个非常大的阶乘,但是它必须是精确的。我不能用近似值 我想得到100000000!,但是速度很慢。到目前为止,我已经提高了一点性能,但仍然不够。以下是我所拥有的: BigInteger Factor100 = BigInteger.One; BigInteger Factor10000 = BigInteger.One; Status = "Factorising"; for (i++; i <= StartN; i
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中所述。原因是我计划用它进行的计算取决于它是精确的数字。什么样的计算?也许解释这个问题会帮助你得到优化的公式,而不需要执行那个多次迭代。您似乎高估了准确性。