计算大方的模数

时间:2017-03-19 11:15:38

标签: algorithm math modulus

我想计算一个正方形的模数:n ^ 2%m,其中n和m都是大数(但小于64位整数的最大值)。当n ^ 2大于64位最大值时,问题就出现了。

是否有可用于执行此计算的算法?我知道n ^ 2%m =(n%m)^ 2%m,但是当m>时,这对我没有帮助。 Ñ

2 个答案:

答案 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。