【发布时间】:2018-08-05 14:43:13
【问题描述】:
我正在使用以下函数来计算以 m 为模的大数的幂,其中 m 是任何整数,即(a^b)%m
long long power(long long x, long long y, long long p)
{
long long res = 1; // Initialize result
x = x % p; // Update x if it is more than or
// equal to p
while (y > 0)
{
// If y is odd, multiply x with result
if (y & 1)
res = (res*x) % p;
// y must be even now
y = y>>1; // y = y/2
x = (x*x) % p;
}
return res;
}
但是,对于某些数字,即使此功能也不起作用。例如,如果我调用
power(1000000000000,9897,52718071807);
我得到一个负数作为输出。它的发生是由于以下原因: 幂函数中有一行:
x = (x*x) % p;
当 x 很大时,假设 x=46175307575,执行 x=(x * x)%p 后存储在 x 中的值变为负数。我不明白为什么会这样。即使 (x * x) 的值超过了 long long int 的上限,我也不会将其值存储在任何地方,我只是存储 (x*x)%p ,其值应介于 0 到 p 之间。此外,由于 p 不跨越长距离,x 如何跨越它?请告诉我为什么会出现这个问题以及如何解决这个问题。
【问题讨论】:
-
x*x仍被评估为long long,您有一个有符号整数溢出,这会导致未定义的行为。 -
了解two's complement,这是表示负数的最常用方式。也许使用
unsigned数字看看是否有帮助?如果没有,那么您需要一个 bignum 库。 -
所以你需要实现乘以求和
-
你应该看看 chux Modular exponentiation without range restriction 的这篇文章
标签: c algorithm function long-long