c – 大数乘法的模数

参见英文答案 > Need help in mod 1000000007 questions3个
> How can I calculate (A*B)%C for A,B,C <= 10^18,in C++?2个
> Compute (a*b)%m FAST for 64-bit unsigned arguments in C(++) on x86-64 platforms?4个
是的我知道这个问题可能看起来很幼稚但我在谷歌和这个网站上搜索了很多但是找不到令人满意的答案.
我只想计算(A * B)%MOD,假设a长很长,那么b和MOD也是如此.
假设MOD大于A和B,使得A%MOD = A且B%MOD = B但A * B大于64位.如何计算(A * B)%MOD的正确值?

解决方法

这里的基本思想是首先定义一个非溢出的addmod函数,该函数利用其算术中的负数.然后根据它使用位操作定义timesmod.时间复杂度为O(N),其中N是使用的比特数(在这种情况下为64).
#include <iostream>
using namespace std;

typedef long long BigInt; // must be signed,to detect overflow

BigInt A = 0x7fffffffffffff01;
BigInt B = 0x7fffffffffffff02;
BigInt M = 0x7fffffffffffff03;

// For simplicity it is assumed x,y,and m are all positive.
BigInt addmod( BigInt x,BigInt y,BigInt m )
{
  x %= m;
  y %= m;
  BigInt sum = x-m+y; // -m <= sum < m-1
  return sum < 0 ? sum + m : sum;
}

BigInt timesmod( BigInt x,BigInt m )
{
  x %= m;
  y %= m;
  BigInt a = x < y ? x : y; // min
  BigInt b = x < y ? y : x; // max
  BigInt product = 0;
  for (; a != 0; a >>= 1,b = addmod(b,b,m) )
    if (a&1) product = addmod(product,m);
  return product;
}

int main()
{
  cout << "A = " << A << endl;
  cout << "B = " << B << endl;
  cout << "M = " << M << endl;
  cout << "A*B mod M = " << timesmod(A,M) << endl;
  return 0;
}

输出

A = 9223372036854775553
B = 9223372036854775554
M = 9223372036854775555
A*B mod M = 2

这很容易确认,因为A = -2且B = -1 mod M.

注意:此代码未进行优化.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...