我想验证是否
pow(a,b)%b == a
在C中为真,2≤b≤32768(2 15 )且2≤a≤b,a和b为整数。
但是,直接计算pow(a, b) % b
且b为大数,这将很快导致C溢出。什么是验证这种情况是否成立的技巧/有效方法?
这个问题的基础是找到费马小定理的见证人,该定理指出如果这个条件是假的,那么b就不是素数。
此外,我的时间也有限,它可能太慢(接近或超过2秒)。最大的Carmichael数字,b
数不是素数,但也不满足pow(a, b)% b == a
2 <= a <= b
(b <= 32768)是29341。因此使用pow(a, b) % b == a
检查2 <= a <= 29341
的方法不应该太慢。
答案 0 :(得分:5)
您可以使用Exponentiation by squaring方法。
这个想法如下:
b
并分解产品%b
,因此结果将始终适合32位数字。所以C代码是:
/*
* this function computes (num ** pow) % mod
*/
int pow_mod(int num, int pow, int mod)
{
int res = 1
while (pow>0)
{
if (pow & 1)
{
res = (res*num) % mod;
}
pow /= 2;
num = (num*num)%mod;
}
return res;
}
答案 1 :(得分:3)
你正在Z / bZ进行模运算。
注意,在商环中,元素类的n次幂是元素的n次幂的类,因此我们得到以下结果:
(a^b) mod b = ((((a mod b) * a) mod b) * a) mod b [...] (b times)
因此,您不需要大整数库。
您可以使用以下算法(伪代码)编写C程序:
(temp * a) mod b
,以获取新的临时值。使用此公式,您可以看到temp的最高值为32768,因此您可以选择整数来存储临时值。