Modulus Function to Avoid Integer Overflow in C++

旧时模样 提交于 2021-02-08 07:29:40

问题


If I have 2 int or long long variables, call them a and b, and I want to compute the sum (a + b) mod p, where p is a large prime integer, how can I utilize the modulo operator in C++ to achieve the desired result?

I have tried (a + b) % p, but this gives overflow sometimes, since a + b will overflow before the mod is applied.

Other similar approaches I have tried seem to avoid overflow, but give an incorrect result.

How can I use the modulo operator in this case to correctly compute the desired sum, while avoiding overflow?


回答1:


a %= p
b %= p
c = p-a

if(b==c)
  sum = 0
if (b<c)
 sum = a+b
if (b>c)
 sum = b-c

EDIT: The trick is to avoid any calculation that might cause overflow, without knowing where the limit is. All we know is that the given a, b and p are below the limit -- maybe just below the limit.

After the first two steps (a%=p;b%=p;) we know a<p and b<p. We still daren't add a+b, because that sum might exceed p and break the limit*. But we can see how much room we have left with c = p-a, which is safe because we know that c<=p and c>0. (The stated types are unsigned, but we may as well avoid negative numbers, if only because their limits are sometimes off by one from the negatives of the positive limits, in ways I can never remember.)

If b=c, then b=p-a, so a+b=p, so the sum (mod p) is zero.

If b<c, then a+b<p, so we can safely compute a+b (and need not apply the modulo).

if b>c, then it is not safe to compute a+b, but we know that the number we're looking for is a+b-p, which we can rewrite as b-(p-a), and we already have b and p-a, so we can safely perform that subtraction.

(*) That's right, I said "daren't". It's a perfectly good word.




回答2:


There is a distributive rule, but you have to apply the mod operator a last time. See this answer for the math.

So (a + b) % p becomes ( (a % p) + (b % p) ) % p.



来源:https://stackoverflow.com/questions/61923686/modulus-function-to-avoid-integer-overflow-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!