模函数,避免C++整数溢出

Modulus Function to Avoid Integer Overflow in C++

本文关键字:整数 溢出 C++ 避免 函数      更新时间:2023-10-16

如果我有 2 个intlong long变量,请将它们称为ab,我想计算(a + b) mod p和,其中 p 是一个大的素数,我怎样才能利用 C++ 中的模运算符来达到预期的结果?

我已经尝试过(a + b) % p,但这有时会溢出,因为a + b会在应用 mod 之前溢出。

我尝试过的其他类似方法似乎可以避免溢出,但给出的结果不正确。

在这种情况下,如何使用取模运算符来正确计算所需的总和,同时避免溢出?

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

编辑:诀窍是避免任何可能导致溢出的计算,而不知道限制在哪里。我们所知道的是,给定的a,b和p低于极限 - 也许刚好低于极限。

在前两个步骤(a%=p;b%=p;(之后,我们知道a<pb<p。我们仍然不敢添加a+b,因为该总和可能会超过 p 并突破限制*。但是我们可以看到我们还剩下多少空间c = p-a,这是安全的,因为我们知道c<=pc>0.(所述类型是无符号的,但我们也可以避免负数,如果只是因为它们的极限有时会与极限的负数相差一,这是我永远记不清的方式。

如果 b=c,则 b=p-a,所以 a+b=p,所以总和 (mod p( 为零。

如果b<c,则a+b<p,因此我们可以安全地计算a+b(并且不需要应用模(。

如果b>c,那么计算a+b是不安全的,但我们知道我们要找的数字是a+b-p,我们可以将其重写为b-(p-a),并且我们已经有bp-a,因此我们可以安全地执行该减法。

(*(没错,我说"不敢"。这是一个非常好的词。