c++ - 在 C++ 中避免整数溢出的模函数
问题描述
如果我有 2 int
orlong long
变量,调用它们a
and b
,并且我想计算 sum (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<p
和b<p
。我们仍然不敢加a+b
,因为这个总和可能超过 p 并打破限制*。但是我们可以看到我们还剩下多少空间c = p-a
,这是安全的,因为我们知道c<=p
并且c>0
。(声明的类型是无符号的,但我们也可以避免负数,如果只是因为它们的限制有时会偏离正限制的负数,以我永远记不得的方式。)
如果 b=c,则 b=pa,所以 a+b=p,所以和 (mod p) 为零。
如果b<c
,则a+b<p
,所以我们可以安全地计算a+b
(并且不需要应用模数)。
如果b>c
,那么计算 是不安全的,a+b
但是我们知道我们正在寻找的数字是a+b-p
,我们可以将其重写为b-(p-a)
,并且我们已经有了b
和p-a
,因此我们可以安全地执行减法。
(*)没错,我说“不敢”。这是一个非常好的词。
推荐阅读
- angular - Angular --prod build 从编译的 CSS 中去除 SVG 属性
- python - [以天为单位的年龄]如何将posix时间转换为日期时间并从当前时间中减去以获取年龄?
- python - 在 Python 中使用 BeautifulSoup 从 HTML 脚本标签中提取 JSON
- javascript - Vuejs2 firebase在数据更改失败时执行一个函数
- python - How do I sort a dictionary by a value when the value is 3 levels deep?
- mongodb - Mongoose:对数组进行索引时提示错误
- react-native - React-Native/Expo Location permissions issues
- django - 401 在 Django Rest Framework 中的 405 之前提出
- javascript - ReactJS:超过最大更新深度(私人路线,登录,主页)
- sprite-kit - 相对于在 Spritekit 中移动的另一个精灵移动精灵