简体   繁体   English

为什么我们不需要在Fast Power算法中对每个操作数执行模运算?

[英]Why don't we need to perform modulo operation on every operands in Fast Power algorithm?

Today I practiced with a puzzle "fast power", which used a formula: (a * b) % p = (a % p * b % p) % p to calculate (a^n)%p , something like that: 2^31 % 3 = 2 今天,我练习了一个难题“快速力量”,其中使用了一个公式: (a * b) % p = (a % p * b % p) % p来计算(a^n)%p ,类似这样: 2^31 % 3 = 2

However, I am so confused when I found the answer used ((temp * temp) % b * a) % b; 但是,当我找到所使用的答案时,我感到非常困惑((temp * temp) % b * a) % b; to solved situation when n is odd, like 2^3 解决n为奇数时的情况,例如2^3

(temp is (temp * temp) % b * a recursively or (temp * temp) % b ). (temp是(temp * temp) % b * a递归或(temp * temp) % b )。

Should not it be ((temp * temp) % b * a%b) % b ? 它应该不是((temp * temp) % b * a%b) % b吗?

Since according to this formula, everything should %b before times together. 由于根据此公式,所有内容都应先%b次在一起。

Should not it be ((temp * temp) % b * a % b) % b ? 应该不是((temp * temp) % b * a % b) % b吗?

No. For a , if you know beforehand that a won't overflow(a is smaller than b), you don't have to mod it. 否。对于a ,如果您事先知道a不会溢出(a小于b),则无需进行修改。

The idea is modular arithmetic works for addition and multiplication. 这个想法是用于加法和乘法的模块化算术工作。 Operation like (a + b) % M = (a % M + b % M) % M and (a * b) % M = (a % M * b % M) % M are generally performed to avoid overflow of (a * b) and (a + b) and keep the value under certain range. 通常执行(a + b) % M = (a % M + b % M) % M(a * b) % M = (a % M * b % M) % M这样的操作以避免(a * b)(a + b)并将值保持在一定范围内。

Example: 例:

const int Mod = 7;
int a = 13;
int b = 12;
int b = b % Mod; // b now contains 5 which is certainly smaller than Mod

int x = (a % Mod * b) % Mod; // you won't need to mod b again if you know beforehand b is smaller than Mod

Update 更新资料

C++ implementation of power function: C ++幂函数的实现:

#define MOD 1000000007
// assuming x and n both be positive and initially smaller than Mod
int power(int x, int n) {
    if(n == 0) return x;
    int half = power(x, n / 2) % Mod;
    int ret = (half * half) % Mod; // you didn't need to do (half % Mod * half % Mod) % Mod because you already know half is smaller than Mod and won't overflow. 
                                   // Modulas being performed on the multiplied output, so now ret will be smaller than Mod
    if(n & 1) {
        ret = (ret * x) % Mod; // you didn't need to do (ret % Mod * x % Mod) % Mod
                               // because you already know ret and x is smaller than Mod
    }
    return ret;
}

Mod is an expensive operation. Mod是一项昂贵的操作。 So you should avoid it whenever possible. 因此,您应尽可能避免使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM