Ways to do modulo multiplication with primitive types

后端 未结 7 2104
野趣味
野趣味 2020-12-05 08:13

Is there a way to build e.g. (853467 * 21660421200929) % 100000000000007 without BigInteger libraries (note that each number fits into a 64 bit integer but the

7条回答
  •  一整个雨季
    2020-12-05 09:06

    Both methods work for me. The first one is the same as yours, but I changed your numbers to excplicit ULL. Second one uses assembler notation, which should work faster. There are also algorithms used in cryptography (RSA and RSA based cryptography mostly I guess), like already mentioned Montgomery reduction as well, but I think it will take time to implement them.

    #include 
    #include 
    
    __uint64_t mulmod1(__uint64_t a, __uint64_t b, __uint64_t m) {
      if (b < a)
        std::swap(a, b);
      __uint64_t res = 0;
      for (__uint64_t i = 0; i < a; i++) {
        res += b;
        res %= m;
      }
      return res;
    }
    
    __uint64_t mulmod2(__uint64_t a, __uint64_t b, __uint64_t m) {
      __uint64_t r;
      __asm__
      ( "mulq %2\n\t"
          "divq %3"
          : "=&d" (r), "+%a" (a)
          : "rm" (b), "rm" (m)
          : "cc"
      );
      return r;
    }
    
    int main() {
      using namespace std;
      __uint64_t a = 853467ULL;
      __uint64_t b = 21660421200929ULL;
      __uint64_t c = 100000000000007ULL;
    
      cout << mulmod1(a, b, c) << endl;
      cout << mulmod2(a, b, c) << endl;
      return 0;
    }
    

提交回复
热议问题