我有2个号码:A和B.我需要A+B在代码中的某处计算.这两个A和B的long long,并可以积极或消极的.
我的代码运行错误,我怀疑计算时会出现问题A+B.我只想检查是否A+B超出long long范围.因此,任何方法都是可以接受的,因为我只将它用于调试.
Dan*_*her 31
仅当两个数字具有相同符号时才可能溢出.如果两者都是正数,那么无论是数学A + B > LLONG_MAX还是等效,都会溢出B > LLONG_MAX - A.由于右侧是非负的,后一种情况已经暗示B > 0.类似的论点表明,对于否定的情况,我们也不需要检查符号B(感谢Ben Voigt指出签名检查B是不必要的).然后你可以检查
if (A > 0) {
return B > (LLONG_MAX - A);
}
if (A < 0) {
return B < (LLONG_MIN - A);
}
return false;
Run Code Online (Sandbox Code Playgroud)
检测溢出.由于初始检查,这些计算不会溢出.
检查结果的符号A + B将有效保证溢出整数计算的环绕语义.但是有符号整数的溢出是未定义的行为,即使在环绕是实现行为的CPU上,编译器也可能认为没有发生未定义的行为,因此在实现时完全删除溢出检查.因此,对问题的评论中建议的检查非常不可靠.
类似于以下内容:
long long max = std::numeric_limits<long long>::max();
long long min = std::numeric_limits<long long>::min();
if(A < 0 && B < 0)
return B < min - A;
if(A > 0 && B > 0)
return B > max - A;
return false;
Run Code Online (Sandbox Code Playgroud)
我们可以这样解释如下:
如果A和B符号相反,他们不能溢出-大于零的一个更大的需要是大于max或一个小于零,将需要不到min.
在其他情况下,简单的代数就足够了.A + B > max => B > max - A如果他们都是积极的,他们会溢出 否则,如果他们都是负面的,A + B < min => B < min - A.