在计算(a * b)%c时a,b,c在c中的(x)e + 18的量级

时间:2014-01-14 10:15:20

标签: c math mathematical-optimization

我找到这两个代码来计算(a * b)%c当a,b,c大约为10 ^ 18时,但无法得到它们如何工作,任何人都能解释我这些函数如何逐行工作

long long int mult(long long int x, long long int y, long long int mod)
{
    x = x % mod;
    y = y % mod;
    long long int z = 0;
    for (1; x; x >>= 1){
            if(x & 1)
            if((z =z+ y) >= mod)
               z = z- mod;
            if((y = 2 * y) >= mod)
           y =y- mod;
     }
     return z;
}

long long multiple(long long a, long long b, long long c) // a * b % c
{
        if (b == 0) 
           return 0;

        long long ret = multiple(a, b >> 1, c);
        ret = (ret + ret) % c;
        if (b & 1) 
             ret = (ret + a) % c;
        return ret;
}

我已经使用这些功能来解决在线比赛,我已经看到第一个功能比后者更好/更快,但为什么呢?

1 个答案:

答案 0 :(得分:0)

比特移位将乘法运算转换为(条件)加法。每次循环(第一种方法)或递归调用(第二种方法)时,代码会查看其中一个操作数的最低有效位:如果已设置,则将另一个操作数添加到运行总计中。然后它将第一个操作数向右移动(除以2)并将另一个操作数加倍(如果需要,使用模数或减法)。

例如,如果数字是5和7,5 == 101二进制,那么:

x      y      z
--     ---    ---
101    7      7   (bottom bit set, add 7 to z)
10     14         ( x = x >> 1 ; y = y * 2 )
10     14     7   (bottom bit not set, don't add)
1      28     7   ( x = x >> 1 ; y = y * 2 )
1      28     35  (bottom bit set, add 28 to z)
0                 ( x = x >> 1 ; x is zero so stop)