计算大正方形的模数
Calculating the modulus of a large square
我想计算一个正方形的模数:n^2 % m,其中 n 和 m 都是大数(但小于 64 位整数的最大值)。当 n^2 大于 64 位最大值时,就会出现问题。
是否有可用的算法来进行此计算?我知道 n^2 % m = (n % m)^2 %m,但是当 m > n.
时这对我没有帮助
令 n = k * 232 + j 其中 j, k < 232。那么n^2%m=(264k2+2*k*j*232 + j2) % 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;
}
根据 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。
我想计算一个正方形的模数:n^2 % m,其中 n 和 m 都是大数(但小于 64 位整数的最大值)。当 n^2 大于 64 位最大值时,就会出现问题。
是否有可用的算法来进行此计算?我知道 n^2 % m = (n % m)^2 %m,但是当 m > n.
时这对我没有帮助令 n = k * 232 + j 其中 j, k < 232。那么n^2%m=(264k2+2*k*j*232 + j2) % 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;
}
根据 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。