--------------------------------------------------
Calculating the OVERFLOW flag in binary arithmetic
--------------------------------------------------
- Ian! D. Allen - idallen@idallen.ca - www.idallen.com
Do not confuse "carry" with "overflow".
If you treat the bits in a word as "unsigned" numbers, you must watch
to see if your arithmetic causes a "carry", indicating the result is
wrong. You don't care about the overflow flag when doing unsigned math.
(The overflow flag is only relevant to signed numbers, not unsigned.)
If you treat the bits in a word as "two's complement" signed values, you
must watch to see if your arithmetic causes an "overflow", indicating the
result is wrong. You don't care about the carry flag when doing signed,
two's complement math. (The carry flag is only relevant to unsigned
numbers, not signed.)
The rules for detecting overflow in a two's complement sum are these:
In two's complement arithmetic, the overflow flag is set if the answer
is wrong - you added two positive numbers and got a negative, or you
added two negative numbers and got a positive.
1. If the sum of two positive numbers yields a negative result, the sum
has overflowed, the "overflow" flag is turned on.
2. If the sum of two negative numbers yields a positive result, the sum
has overflowed, the "overflow" flag is turned on.
Otherwise, the sum has not overflowed. It is important to note the
overflow and carry out can each occur without the other. In unsigned
numbers, carry out is equivalent to overflow. In twos compliment, carry
out tells you nothing about overflow.
The rules for "overflow" detect this error by examining the sign of
the result. A negative and positive added together cannot overflow,
because the sum is between the addends. Since both of the addends fit
within the allowable range of numbers, and their sum is between them,
it must fit as well.
There are several automated ways of detecting overflow in two's complement
binary arithmetic (for those of you who don't like the manual inspection
method). Here are two.
========
Method 1
========
Overflow can only happen when "adding" two numbers of the same sign and
getting a different sign. So, to detect overflow we don't care about
any bits except the sign bits. Ignore the other bits.
With two operands and one result, we have three sign bits (each 1 or 0)
and one operation to consider. The operation is either ADD or SUBTRACT;
so, we have only 2**4=16 possible combinations of the three bits and
the operation. Only four of those 16 possible cases are considered
overflow, and two of those are simple variations of the other two:
Below are just the sign bits of the two operands and result:
0+0=0
*OVER* 0+0=1 (adding two positives should be positive)
0+1=0
0+1=1
0-0=0
0-0=1
0-1=0
*OVER* 0-1=1 (subtracting a negative is the same as adding a positive)
1+0=0
1+0=1
*OVER* 1+1=0 (adding two negatives should be negative)
1+1=1
*OVER* 1-0=0 (subtracting a positive is the same as adding a negative)
1-0=1
1-1=0
1-1=1
There are 12 combinations of sign bits above that are not overflow.
A computer might contain a small logic gate array that sets the overflow
flag to "1" iff any one of the above four OV conditions is met.
A human need only remember that adding two numbers of the same sign
must produce a result of the same sign, otherwise overflow happened.
========
Method 2
========
When adding two binary values, consider the binary carry coming into
the leftmost place (into the sign bit) and the binary carry going out
of that leftmost place. (Carry going out of the leftmost [sign] bit
becomes the CARRY flag in the ALU.)
The reason for the rules is that overflow in two's complement may occur,
not when a bit is carried out out of the left column, but when one is
carried into it and no matching carry occurs. That is, when there is
a carry into the sign bit but no carry out of the sign bit.
The OVERFLOW flag is the XOR of the carry coming into the sign bit (if
any) with the carry going out of the sign bit (if any). Overflow happens
if the carry in does not equal the carry out.
Examples (2-bit signed 2's complement binary numbers):
11
+01
===
00
- carry in is 1
- carry out is 1
- 1 XOR 1 = NO OVERFLOW
01
+01
===
10
- carry in is 1
- carry out is 0
- 1 XOR 0 = OVERFLOW!
11
+10
===
01
- carry in is 0
- carry out is 1
- 0 XOR 1 = OVERFLOW!
10
+01
===
11
- carry in is 0
- carry out is 0
- 0 XOR 0 = NO OVERFLOW
Note that this XOR method only works with the *binary* carry that goes
into the sign *bit*. If you are working with hexadecimal numbers, or
decimal numbers, or octal numbers, you also have carry; but, the carry
doesn't go into the sign *bit* and you can't XOR that non-binary carry
with the outgoing carry.
Hexadecimal addition example (showing that XOR doesn't work for hex carry):
8Ah
+8Ah
====
14h
The hexadecimal carry of 1 resulting from A+A does not affect the
sign bit. If you do the math in binary, you'll see that there is
*no* carry *into* the sign bit; but, there is carry out of the sign
bit. Therefore, the above example sets OVERFLOW on. (The example
adds two negative numbers and gets a positive number.)