将两个溢出的整数乘以模三分之一

时间:2013-02-13 16:41:33

标签: c bit-manipulation

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

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

2 个答案:

答案 0 :(得分:7)

这里并不真正需要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).

(并且没有再次溢出)。

答案 1 :(得分:0)

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