快速功率算法实现

时间:2015-10-16 04:30:07

标签: c++ algorithm

我需要计算二次残差。 Prime p是3 mod 4,是一个非常大的数字,约为1e38(constexpr)。我只找到了拉格朗日x = +- a^((p + 1)/4) mod p的公式。

我需要计算大数字的幂(a ^ 1e38)。我试图使用boost::multiprecision::cpp_int,但似乎没有任何意义。对于这样的计算或替代算法,可能有人知道一个很好的实现。

3 个答案:

答案 0 :(得分:1)

你的例子要求模数运算模数为素数。如https://en.wikipedia.org/wiki/Fermat%27s_little_theorem中所述,其中p是素数a ^ p mod p = a,并且如果a不是p的倍数,则a ^(p-1)= 1 mod p。所以如果a = = 0,则a ^ x = a ^(x mod p-1)。如果你想要一个模数不是素数的东西,那么考虑它并使用https://en.wikipedia.org/wiki/Chinese_remainder_theorem

如果你想要实数的算术,使用^ x = exp(x * ln(a))但是对于大x你可能需要将它保持为对数以避免溢出。

答案 1 :(得分:1)

通常,测试某些东西是否为二次剩余是通过欧几里德算法式计算完成的,通过二次互易调用​​,只要顶部小于底部,就可以翻转雅可比符号(或Kronecker符号)。

此外,你几乎不应该计算指数然后减去模p:你的指数算法(例如,square-and-multiply)应该在每次之后减少模p步数左右计算。关键词:"模幂运算"。

答案 2 :(得分:0)

我认为这可能会有所帮助 https://www.geeksforgeeks.org/modular-exponentiation-power-in-modular-arithmetic/

/* Iterative Function to calculate (x^y) in O(log y) */

int power(int x, unsigned int y) 
{ 

    int res = 1;     // Initialize result 

    while (y > 0) 
    { 
        // If y is odd, multiply x with result 
        if (y & 1) 
            res = res*x; 

        // y must be even now 
        y = y>>1; // y = y/2 
        x = x*x;  // Change x to x^2 
    } 
return res; 
}