【问题标题】:Multiply two overflowing integers modulo a third将两个溢出的整数以三分之一为模相乘
【发布时间】:2013-02-13 16:41:32
【问题描述】:

给定三个整数,abca,b <= c < INT_MAX,我需要计算(a * b) % c,但如果值太大,a * b 可能会溢出,从而给出错误的结果。

有没有办法通过 bithacks 直接计算,即不使用不会溢出相关值的类型?

【问题讨论】:

  • 必须和Ivella上同一堂课:stackoverflow.com/questions/14857702/…
  • 不,我只是减少我的问题,直到它们听起来像家庭作业...... Katabusa 似乎很投入,我希望我错过了一些明显的位黑客(比如链接中提到的(a % c) * (b % c) % c,它但不适用于我的问题……)
  • @MatsPetersson If a
  • Overflow: a*a mod n 的可能重复项(具体请参见此处的my answer)。这是为了平方,但可以很容易地适应任意乘法。

标签: c bit-manipulation


【解决方案1】:

这里并不需要 Karatsuba 的算法。将操作数拆分一次就足够了。

为了简单起见,假设您的数字是 64 位无符号整数。设 k=2^32。那么

a=a1+k*a2
b=b1+k*b2
(a1+k*a2)*(b1+k*b2) % c = 
   a1*b1 % c + k*a1*b2 % c + k*a2*b1 % c + k*k*a2*b2 % c

现在a1*b1 % c 可以立即计算,其余的可以通过交替执行x <<= 1x %= c 32 或 64 次来计算(因为 (u*v)%c=((u%c)*v) %C)。如果c >= 2^63,这表面上可能会溢出。然而,好消息是这对操作不需要按字面意思执行。要么x < c/2,然后你只需要一个班次(并且没有溢出),或者x >= c/2

2*x % c = 2*x - c = x - (c-x).

(并且没有再次溢出)。

【讨论】:

    【解决方案2】:

    一些主要编译器提供 128 位整数类型,您可以使用它进行此计算而不会溢出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      • 1970-01-01
      • 2017-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-30
      相关资源
      最近更新 更多