我想计算一个正方形的模数:n ^ 2%m,其中n和m都是大数(但小于64位整数的最大值)。当n ^ 2大于64位最大值时,问题就出现了。
是否有可用于执行此计算的算法?我知道n ^ 2%m =(n%m)^ 2%m,但是当m>时,这对我没有帮助。 Ñ
答案 0 :(得分:2)
令n = k * 2 32 + j其中j,k <1。 2 32 。然后n ^ 2%m =(2 64 k 2 + 2 * k * j * 2 32 + j 2 )%m
#include <iostream>
int main()
{
uint64_t n = 17179874627;
uint64_t m = 27778894627;
uint64_t k = n >> 32;
uint64_t j = n & 4294967295;
uint64_t a = (k * k) % m; // k^2
a = (65536 * a) % m; // 2^16 * k^2
a = (65536 * a) % m; // 2^32 * k^2
a = (65536 * a) % m; // 2^48 * k^2
a = (65536 * a) % m; // 2^64 * k^2
uint64_t b = (j * 65536) % m;
b = (b * 65536) % m; // j * 2^32
b = (b * k) % m; // k * j * 2^32
b = (2 * b) % m; // 2 * k * j * 2^32
uint64_t c = (j * j) % m; // j^ 2
std::cout << "Result " << (a + b + c) % m;
}
答案 1 :(得分:0)
根据invisal的回答,我将其扩展为Delphi代码(n1 * n2)%m:
k1 := n1 shr 30;
j1 := n1 and 1073741823; // = 2^30 - 1
k2 := n2 shr 30;
j2 := n2 and 1073741823;
a1 := (k1 * k2) mod m;
for i := 1 to 4 do
a1 := (32768 * a1) mod m;
a2 := (k1 * j2) mod m;
for i := 1 to 2 do
a2 := (32768 * a2) mod m;
a3 := (k2 * j1) mod m;
for i := 1 to 2 do
a3 := (32768 * a3) mod m;
a4 := (j1 * j2) mod m;
Result := (a1 + a2 + a3 + a4) mod m;
请注意,Delphi没有无符号的64位整数,因此我使用2 ^ 30而不是2 ^ 32。