BigInteger.Pow(BigInteger, BigInteger)?

8
我正在尝试计算一个很大的数字,需要使用BigInteger.Pow(),但是指数也需要是BigInteger而不是int
例如:
BigInteger.Pow(BigInteger)

我该如何实现这个?

编辑:我想到了一个答案。用户dog帮助我实现了这个。

public BigInteger Pow(BigInteger value, BigInteger exponent)
{
    BigInteger originalValue = value;
    while (exponent-- > 1)
        value = BigInteger.Multiply(value, originalValue);
    return value;
}

7
你确定你需要那么大的数字吗? - Rufus L
重复的问题:https://dev59.com/jG455IYBdhLWcg3wAvbQ?rq=1 - austin wernli
我同意@RufusL的观点,int支持最大约为20亿,你真的需要将某物提高到20亿的幂次吗? - Matthew
3
@Matthew 是的,20亿不足以计算它。 - avi12
我已经编辑了你的标题。请参考“问题的标题应该包含“标签”吗?”,在那里达成共识是“不应该”。 - John Saunders
5个回答

9

仅从一般数学的角度来看,这是没有意义的。这就是为什么它没有被实现的原因。

想象一下这个例子:你的BigInteger数字是2,你需要将其平方1024次方。这意味着结果是一个1 KB的数字(2^1024)。现在想象一下你取int.MaxValue:那么,你的数字会占用2 GB的内存。使用BigInteger作为指数会产生超出内存容量的数字!


如果你的应用程序需要这个规模的数字,而数字本身太大,无法存储在内存中,你可能需要一种将数字和指数分开存储的解决方案,但这只是我根据你的问题推测的。


如果你的问题是指数变量是BigInteger,那么你可以将其转换为int:

BigInteger.Pow(bigInteger, (int)exponent); // exponent is BigInteger

1
当然,如果他有一个小于20亿的BigInteger值,他可以在将其传递给pow之前将其转换为Int32,如果这是他关心的问题。 - Servy
这个数字太大了,不能使用 int。一个需要计算的大数示例:Googleplex - avi12
2
Googleplex不能被存储为一个数字,它将会消耗超出想象的内存(10^100字节)。你需要这些数字做什么,为什么不能在理论上处理它们,而不是实际存储这个数字呢? - bytecode77
1
Googol是10的100次方。但Googolplex是10的10的100次方。因此,它不能简单地计算出来。 - avi12
2
那么,你已经回答了自己的问题 ;) - bytecode77
结果是一个1KB的数字,你的数字将消耗2GB的内存:不完全正确。它们将消耗1Kb和2Gb(注意小写的b代表位,而不是字节)。这仍然很多,但是只有原来的1/8内存。 - Bip901

5

为了让你更好地理解,Pow(2, int64.MaxValue)所需的存储空间达到了1,152,921太字节。但是,如果你拥有非常强大的计算机,这里提供了该函数的代码。

  static BigInteger Pow(BigInteger a, BigInteger b) {
     BigInteger total = 1;
     while (b > int.MaxValue) {
        b -= int.MaxValue ;
        total = total * BigInteger.Pow(a, int.MaxValue);
     }
     total =  total * BigInteger.Pow(a, (int)b);
     return total;
  }

2
你很有趣 :D 或许一千年后,有人会偶然发现这篇帖子并嘲笑我们只拥有几GB的内存... - bytecode77
当我尝试使用这个方法时,我得到了“System.OutOfMemoryException类型的异常被抛出。” 我能在不抛出异常的情况下执行这个操作吗? - avi12
一台只有1位内存的计算机可以存储0到1之间的数字,而一台有100位内存的计算机可以存储0到(2^100)-1之间的数字。你能计算的最大数字约为Pow(2,可用位数)。因此,如果你没有足够的内存,上述函数将无法工作,因此会出现“System.OutOfMemoryException”异常。 - dog
2
"1,152,921 terabytes应该足够了。" - codekaizen

1
对我来说,解决方案是使用函数 BigInteger.ModPow(BigInteger value, BigInteger exponent, BigInteger modulus),因为我之后需要进行模运算。

该函数计算给定的 BigInteger 的另一个 BigInteger 次幂,并使用第三个 BitInteger 计算模数。 虽然它仍需要大量的 CPU 力量来评估,但由于该函数已经知道模数,因此可以节省大量内存。

希望这可以帮助一些有相同问题的人。

编辑: 自 .Net Framework 4.0 可用,并且在 .Net Standard 1.1 及更高版本中可用。


1
正如其他人指出的那样,将某个数提高到超过 int 容量的幂次方是不好的消息。但是,假设您已经意识到这一点,并且只是以 BigInteger 的形式给出您的指数,那么您可以将其转换为 int 并继续前进:
BigInteger.Pow(myBigInt, (int)myExponent);

或者,更好的是,
try
{
    BigInteger.Pow(myBigInt, (int)myExponent);
}
catch (OverflowException)
{
    // Do error handling and stuff.
}

0

我想到了:

public BigInteger Pow(BigInteger value, BigInteger exponent)
{
    BigInteger originalValue = value;
    while (exponent-- > 1)
        value = BigInteger.Multiply(value, originalValue);
    return value;
}

2
这个方法在一个比 long.MaxValue 更大的数字上运行需要多长时间? - StriplingWarrior

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接