How do I check if A+B exceed long long? (both A and B is long long)
Overflow is possible only when both numbers have the same sign. If both are positive, then you have overflow if mathematically A + B > LLONG_MAX
, or equivalently B > LLONG_MAX - A
. Since the right hand side is non-negative, the latter condition already implies B > 0
. The analogous argument shows that for the negative case, we also need not check the sign of B
(thanks to Ben Voigt for pointing out that the sign check on B
is unnecessary). Then you can check
if (A > 0) {
return B > (LLONG_MAX - A);
}
if (A < 0) {
return B < (LLONG_MIN - A);
}
return false;
to detect overflow. These computations cannot overflow due to the initial checks.
Checking the sign of the result of A + B
would work with guaranteed wrap-around semantics of overflowing integer computations. But overflow of signed integers is undefined behaviour, and even on CPUs where wrap-around is the implemented behaviour, the compiler may assume that no undefined behaviour occurs and remove the overflow-check altogether when implemented thus. So the check suggested in the comments to the question is highly unreliable.
Something like the following:
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;
We can reason about this as follows:
If
A
andB
are opposite sign, they cannot overflow - the one greater than zero would need to be greater thanmax
or the one less than zero would need to be less thanmin
.In the other cases, simple algebra suffices.
A + B > max => B > max - A
will overflow if they are both positive. Otherwise if they are both negative,A + B < min => B < min - A
.
Also, if you're only using it for debug, you can use the following 'hack' to read the overflow bit from the last operation directly (assuming your compiler/cpu supports this):
int flags;
_asm {
pushf // push flag register on the stack
pop flags // read the value from the stack
}
if (flags & 0x0800) // bit 11 - overflow
...