有没有办法做 (A*B) mod M 而不会溢出无符号长 A 和 B

Is there a way to do (A*B) mod M without overflow for unsigned long long A and B?

本文关键字:溢出 无符号 有没有 mod      更新时间:2023-10-16

我不想要在Windows上安装GMP的噩梦。

我有两个数字 A 和 B,unsigned long long s,最多在 10^10 左右的数量级,但即使做((A%M)*(B%M))%M,我也会出现整数溢出。

是否有自制函数来计算较大数字的(A*B)%M

如果模量M足够小于 ULLONG_MAX(如果它在 10^10 的范围内就是这种情况),您可以通过将其中一个因子分成两部分来分三步完成。我假设A < MB < MM < 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则变得丑陋。