幂后取模算法
Algorithm of calculate modulo after power
下面一段代码计算a^b%c的值,
int powermod(int a,int b,int c)
{
int ans = 1;
while(b)
{
if(b&1)
ans=(ans*a)%c;
a=(a*a)%c;
b=b>>1;
}
return ans;
}
我试图理解代码背后的算法,但无法理解。
有人可以帮我解释一下吗?这是如何工作的,它背后的算法有名字吗?
如果没有 "modulo c" 部分,则更容易看到发生了什么:
int power(int a,int b)
{
int ans = 1;
while(b)
{
if(b&1)
ans *= a;
a=a*a;
b=b>>1;
}
return ans;
}
这是计算 ab 的标准算法,一次考虑 b
一位,从最低有效位开始。对于b
的每一位,如果是1
,则将答案乘以a
的当前值。然后,要移动到下一位,对 a
进行平方并将 b
向右移动 1 位。该算法的理论是 x2m + 2n = x 2mx2n.
这种算法称为 "exponentiation by squaring"、"square-and-multiply" 或 "binary exponentiation"。
发布的算法(在评论中指出的更正后)做同样的事情模 c
,使用 (x*y)%z == ((x%z) * (y%z)) % z
的事实(也就是说,模运算可以在之前或之前应用乘法)。它使用它来保持 a
小于 c
尽管重复平方。
使用二元思维
ab = ab1 ab2 ... abn 当 b1+...+bn=b
将b写成二进制,得到ab0 a2*b1 a4*b2 ... a2nbn ,bi表示二进制b中的第i位。只能是0或1。
现在我们发现不需要每次都计算a2n,因为我们可以从a 2n-1
因为(ab)%c=(a%c)(b%c)%c,这个算法在乘法时做mod操作。
下面一段代码计算a^b%c的值,
int powermod(int a,int b,int c)
{
int ans = 1;
while(b)
{
if(b&1)
ans=(ans*a)%c;
a=(a*a)%c;
b=b>>1;
}
return ans;
}
我试图理解代码背后的算法,但无法理解。 有人可以帮我解释一下吗?这是如何工作的,它背后的算法有名字吗?
如果没有 "modulo c" 部分,则更容易看到发生了什么:
int power(int a,int b)
{
int ans = 1;
while(b)
{
if(b&1)
ans *= a;
a=a*a;
b=b>>1;
}
return ans;
}
这是计算 ab 的标准算法,一次考虑 b
一位,从最低有效位开始。对于b
的每一位,如果是1
,则将答案乘以a
的当前值。然后,要移动到下一位,对 a
进行平方并将 b
向右移动 1 位。该算法的理论是 x2m + 2n = x 2mx2n.
这种算法称为 "exponentiation by squaring"、"square-and-multiply" 或 "binary exponentiation"。
发布的算法(在评论中指出的更正后)做同样的事情模 c
,使用 (x*y)%z == ((x%z) * (y%z)) % z
的事实(也就是说,模运算可以在之前或之前应用乘法)。它使用它来保持 a
小于 c
尽管重复平方。
使用二元思维
ab = ab1 ab2 ... abn 当 b1+...+bn=b
将b写成二进制,得到ab0 a2*b1 a4*b2 ... a2nbn ,bi表示二进制b中的第i位。只能是0或1。
现在我们发现不需要每次都计算a2n,因为我们可以从a 2n-1
因为(ab)%c=(a%c)(b%c)%c,这个算法在乘法时做mod操作。