2次幂的模幂运算

时间:2014-07-01 06:20:02

标签: c++ math exponentiation

所以我最近用modpow函数做了一些工作。当模数是2的幂时,我需要的形式之一是模块化指数。所以我得到了代码并运行。太棒了,没问题。然后我读到你可以做得更快的一个技巧是,而不是使用常规指数,取模数的整数。

现在,当模数是2的幂时,答案就是2的幂小于当前的2的幂。嗯,这很简单。所以我编写了它,它有时候工作.....

由于某种原因,有些值不起作用,我只是无法弄清楚它是什么。

uint32 modpow2x(uint32 B, uint32 X, uint32 M)
{
    uint32 D;

    M--;
    B &= M;
    X &= (M >> 1);
    D = 1;
    if ((X & 1) == 1)
    {
        D = B;
    }

    while ((X >>= 1) != 0)
    {
        B = (B * B) & M;
        if ((X & 1) == 1)
        {
            D = (D * B) & M;
        }
    }
    return D;
}

这是一组不起作用的数字。

Base = 593803430
Exponent = 3448538912
Modulus = 8

不,没有检查这个函数来确定模数是否是2的幂。原因是这是一个内部函数,我已经知道只有2的幂将被传递给它。但是,我已经仔细检查过以确保没有2的非幂数。但

感谢你们给予的任何帮助!

1 个答案:

答案 0 :(得分:2)

如果x是相对素数到n(x和n没有公因子),那么x ^ a = x ^(phi(a))(mod n),其中phi是欧拉的全部功能。那是因为那时x属于multiplicative group of (Z/nZ),它有顺序phi(a)。

但是,对于x而言,不是相对于n的素数,这不再是真的。在你的例子中,基数确实与你的模数有一个共同因子,即2.所以这个技巧在这里不起作用。但是,如果你想,你可以编写一些额外的代码来处理这种情况 - 也许找到x的最大幂,即x可被整除,例如2 ^ k。然后将x除以2 ^ k,运行原始代码,将其输出左移k * e,其中e是指数,并减去模M。当然,如果k不为零,这通常会得到答案为零。