为何整数相加一行代码溢出,分步累加却正常?
两种累加写法的本质区别
核心差异在于加法运算的类型范围:
第一种写法
long long sum = a + b + c + d;:
因为a、b、c、d都是int类型,所有加法操作都会在int的范围内执行。如果四个int的总和超过了int的最大值(比如32位int的最大值是2147483647),累加过程中就会触发int类型的溢出,溢出后的结果是未定义的(通常会变成错误数值,比如负数)。最后只是把这个已经出错的int结果转换成long long赋值给sum,自然得不到正确结果。第二种写法
long long sum = a; sum += b; sum += c; sum += d;:
第一步就把int类型的a赋值给了long long类型的sum,此时sum已经是64位长整型。之后每次执行sum += x时,int类型的x会先被自动提升为long long类型,再和sum进行加法运算——所有加法都在long long的大范围内进行,不会触发int的溢出,每一步结果都正确,最终sum能得到四个数的准确总和。
举个实际例子:假设32位int的最大值是2147483647,a=b=c=d=2147483647。第一种写法里,a+b会直接溢出得到-2,后续累加后最终结果是-4;而第二种写法里,sum会依次累加为2147483647、4294967294、6442450941、8589934588,全程都在long long的有效范围内,结果完全正确。
内容的提问来源于stack exchange,提问作者Minion
相关产品推荐
相关产品推荐

