C# 如何从Math.Pow返回BigInteger
我有以下功能:C# 如何从Math.Pow返回BigInteger,c#,math,biginteger,C#,Math,Biginteger,我有以下功能: private static BigInteger Factorial(int number) { if(number < 2) return BigInteger.One; double sum = 0; for(int i = 2; i < number; i++) sum += Math.Log(i); return new BigInteger(Math.Exp(sum)); } return Big
private static BigInteger Factorial(int number)
{
if(number < 2) return BigInteger.One;
double sum = 0;
for(int i = 2; i < number; i++)
sum += Math.Log(i);
return new BigInteger(Math.Exp(sum));
}
return BigInteger.Pow(new BigInteger(Math.E), number);
注意新的biginger(Math.E)
部分biginger.Pow
将biginger
作为第一个参数,因此我别无选择,只能将Math.E
包装为biginger
然而,通过这样做,我实际上截断了我的Math.E
的小数部分,这破坏了我的算法,因为我得到了一个完全不同的结果
我正在寻找类似于bigdoull
或类似的类,但我似乎找到的唯一类是biginger
如何在此函数上成功地将正确的结果返回为
biginger
,同时在接收到大输入时具有异常安全代码?您可以使用base 2而不是base e:
私有静态BigInteger阶乘估计(整数)
{
if(number<2)返回BigInteger.One;
双和=0;
对于(int i=2;i>1;
if(biginger.Pow(mid,n)对于(int i=2;我需要一个精确的值还是一个引用值?你必须找到一个能容纳像50000!
这样的数字的表示法。不double
也不biginger
是合适的。biginger
可以容纳结果,但需要相当长的时间(几秒)计算。你可以使用答案并将其相加。因为他们已经实现了乘法,所以你可以重复乘法得到powers@hege_hegedus我真的需要Math.E
的准确值才能使此算法正常工作。但是Math.Pow
或Math.Exp
的结果可以被截断。@JamEsWebStter我真的试图避免乘法,但我会看一下!我会考虑命名函数<代码> FraceRoalPosivs<代码> -使用整数类型经常给调用方期望精确的结果,这显然不是这个计算中的情况。
private static BigInteger FactorialEstimate(int number)
{
if (number < 2) return BigInteger.One;
double sum = 0;
for (int i = 2; i <= number; i++)
sum += Math.Log(i, 2);
return BigInteger.Pow(2, (int)Math.Round(sum));
}
private static BigInteger NthRoot(BigInteger a, int n)
{
BigInteger min = BigInteger.Zero, max = a, mid = a;
while (min < max)
{
mid = (min + max) >> 1;
if (BigInteger.Pow(mid, n) < a)
min = mid + 1;
else
max = mid;
}
return max;
}
const int Accuracy1 = 16;
const int Accuracy2 = 8;
private static BigInteger FactorialBetterEstimate(int number)
{
if (number < 2) return BigInteger.One;
double sumFractPart = 0;
int sumIntPart = 0, tmpIntPart = 0;
for (int i = 2; i <= number; i++)
{
sumFractPart += Math.Log(i, 2);
tmpIntPart = (int)sumFractPart;
sumFractPart -= tmpIntPart;
sumIntPart += tmpIntPart;
}
int correction = Math.Min(Accuracy2, sumIntPart);
sumIntPart -= correction;
sumFractPart += correction;
return NthRoot(BigInteger.Pow(2, Convert.ToInt32(Accuracy1 * sumFractPart)), Accuracy1) << sumIntPart;
}