我需要计算二次残差。 Prime p是3 mod 4,是一个非常大的数字,约为1e38
(constexpr)。我只找到了拉格朗日x = +- a^((p + 1)/4) mod p
的公式。
我需要计算大数字的幂(a ^ 1e38
)。我试图使用boost::multiprecision::cpp_int
,但似乎没有任何意义。对于这样的计算或替代算法,可能有人知道一个很好的实现。
答案 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;
}