How to judge overflow of sum of two operands?

A

aling

Given: signed a, b;
How to judge overflow of the sum of these two operands? Just use one
*if* statement.

Is this statement right?

if ((a>0 && b>0 && sum<=0) || (a<0 && b<0 && sum>=0))
// overflow
else
// not overflow
 
V

Victor Bazarov

aling said:
Given: signed a, b;
How to judge overflow of the sum of these two operands? Just use one
*if* statement.

Is this statement right?

if ((a>0 && b>0 && sum<=0) || (a<0 && b<0 && sum>=0))

What's "sum"?
// overflow
else
// not overflow

You need to check the values *before* you attempt to add them:

if (INT_MAX - a < b) // will overflow when added

(it's the same as saying
if (a + b > INT_MAX)
without actually attempting to add them.)

And you need to amend this if they are both negative to

if (INT_MIN - a > b)

The final should be

if ( (a > 0 && b > 0 && INT_MAX - a < b) ||
(a < 0 && b < 0 && INT_MIN - a > b) )

// a+b would overflow (or underflow for negative)
else
// no over- or underflow

I am sure somebody will correct me if I made a mistake here.

V
 
K

Kaz Kylheku

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!
 
G

Greg

Kaz said:
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. :)


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++!)

Unsigned integers in C++ do not overflow but instead "wrap around" in
value when their maximum representable value is exceeded. So converting
both operands to unsigned ints and then verifying that their sum is
both greater than either operand and less than MAX_INT should be enough
to detect overflow when adding signed ints:

unsigned sum = unsigned(a) + unsigned(b);

if ( sum > INT_MAX or sum < unsigned(a) or sum < unsigned(b))
{
// error overflow
}

Greg
 
D

Dave Rahardja

unsigned sum = unsigned(a) + unsigned(b);

if ( sum > INT_MAX or sum < unsigned(a) or sum < unsigned(b))
{
// error overflow
}

This test fails for a == b == -1.


--

Note that when the signs of a and b are different, no overflow can occur for a
+ b.

Otherwise, overflow occurs when a > INT_MAX - b (for a and b positive), or a <
INT_MIN - b (for a and b negative).

So a test may be:

if (a > 0 && b > 0) {
if (a > INT_MAX - b) {
// overflow
}
} else if (a < 0 && b < 0) {
if (a < INT_MIN - b) {
// overflow
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top