aling said:
Given: signed a, b;
How to judge overflow of the sum of these two operands? Just use one
*if* statement.
Just one if statement? That must be a homework requirement. Don't
worry; the day will come when you will decide how many if statements
there will be, and get paid.
Is this statement right?
if ((a>0 && b>0 && sum<=0) || (a<0 && b<0 && sum>=0))
// overflow
else
// not overflow
Actually, the sum does not need to be involved. And in fact, if you
have already computed the sum, it is too late. The overflow has
happened (the behavior on overflow is undefined in C++!)
A maximally portable, correct C++ program must not allow overflow to
occur. Here is one way.
#include <climits>
// ...
signed int a, b, c;
// ... assign values ...
if ((a > 0 && b > 0 && a <= INT_MAX - b) ||
(a < 0 && b < 0 && a >= INT_MIN - b))
{
// handle overflow case somehow
}
else
{
c = a + b; // safe
}
The test a <= INT_MAX - b is nothing more than the trivial algebraic
transformation of a + b <= INT_MAX, which avoids computing a + b!
You know that since b > 0 it's safe to subtract INT_MAX - b.
One thing you have to watch out for is that the INT_MIN value on a twos
complement system may have no positive counterpart: it's one less than
the additive inverse of INT_MAX. I.e. the unary minus operator may
overflow!!! E.g.
if (a == INT_MIN && INT_MIN < -INT_MAX) {
// -a will overflow!
} else {
c = -a; // okay.
}
For instance, given a 16 bit twos complement number system, the most
negative number that can be represented is -32768, or 0x8000. But 32768
cannot be represented, because it is 0x10000, out of range. The highest
value is 32767 or 0xFFFF.
If you actually compute the twos complement to invert 0x8000 (flip the
bits, add 1), you get back, guess what, 0x8000!