This question already has an answer here:
- How to detect integer overflow? 31 answers
I have 2 numbers: A
and B
. I need to calculate A+B
somewhere in my code. Both A
and B
are long long
, and can be positive or negative.
My code runs wrong, and I suspect the problem happens when calculating A+B
. I simply want to check if A+B
exceed long long
range. So, any method is acceptable, as I only use it for debug.
Something like the following:
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
.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 equivalentlyB > LLONG_MAX - A
. Since the right hand side is non-negative, the latter condition already impliesB > 0
. The analogous argument shows that for the negative case, we also need not check the sign ofB
(thanks to Ben Voigt for pointing out that the sign check onB
is unnecessary). Then you can checkto 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.Mask the signs, cast to unsigned values, and perform the addition. If it's above
1 << (sizeof(int) * 8 - 1)
then you have an overflow.Better yet, let's write a template:
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):