如何有效地验证pow(a,b)%b == a in C(无溢出)

时间:2017-09-20 08:12:58

标签: c modulus integer-overflow memory-efficient

我想验证是否

  

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的方法不应该太慢。

2 个答案:

答案 0 :(得分:5)

您可以使用Exponentiation by squaring方法。

这个想法如下:

  • 以二进制形式分解b并分解产品
  • 请注意,我们始终使用低于32768的%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程序:

  • 将变量a和b声明为整数。
  • 使用用。
  • 初始化的临时变量temp
  • 使用b步进行循环,并在每一步计算(temp * a) mod b,以获取新的临时值。
  • 将结果与。
  • 进行比较

使用此公式,您可以看到temp的最高值为32768,因此您可以选择整数来存储临时值。