我不想在Windows上安装GMP的噩梦。
我有两个数字A和B,unsigned long long
s,最多只有10 ^ 10左右,但即使做((A%M)*(B%M))%M
,我也会得到整数溢出。
是否有自制函数用于计算较大数字的(A*B)%M
?
答案 0 :(得分:9)
如果模数M
远小于ULLONG_MAX
(如果它在10 ^ 10的范围内就是这种情况),你可以通过分割其中一个因子来分三步完成两部分。我假设A < M
和B < M
以及M < 2^42
。
// split A into to parts
unsigned long long a1 = (A >> 21), a2 = A & ((1ull << 21) - 1);
unsigned long long temp = (a1 * B) % M; // doesn't overflow under the assumptions
temp = (temp << 21) % M; // this neither
temp += (a2*B) % M; // nor this
return temp % M;
对于较大的值,您可以将因子分成三个部分,但如果模数真的接近ULLONG_MAX
则会变得难看。