Suppose that A
and B
are signed positive integers, then for A-B
, it's calculated using A+2
's complement of B
.
For example, in a 4-bit binary system, for signed integers, we have
7-3=0111-0011=0111+1101=(1)0100
,
the 1 in the bracket is the carry bit. According to the overflow rule for signed integer, we know there is no overflow and the result is therefore correct.
However, for unsigned integers, what will happen if we calculate 7-3
? If we use the same way we mentioned above:
7-3=0111-0011=0111+1101=(1)0100
then, according to the overflow rule for unsigned integers, there is an overflow because of the carry out. In another word, 0100
is wrong because there is an overflow. But in fact, we know the result 0100
is correct.
If my analysis is correct, isn't it wrong to use adder to perform unsigned integer subtraction?
In this answer to a related question there's sample code in C that shows how to do subtraction via addition. The code sets the carry and overflow flags as well and contains a simple "test" that adds and subtracts a few numbers and prints the results. The numbers are 8-bit.
EDIT: Formal proof that one can use ADD instead of SUB for unsigned integers AND spot unsigned overflow/underflow as if from SUB.
Let's say we want to calculate a - b
, where a
and b
are 4-bit unsigned integers and we want to perform subtraction via addition and get a 4-bit difference and an underflow/overflow indication when a < b.
a - b = a + (-b)
Since we're operating in modulo-16 arithmetic, -b
= 16-b
. So,
a - b = a + (-b) = a + (16 - b)
If we perform regular unsigned addition of a
and 16-b
the overflow condition for this addition, which is often indicated by the CPU in its carry
flag, will be this (recall that we're dealing with 4-bit integers):
a + (16 - b) > 15
Let's simplify this overflow condition:
a + 16 - b > 15
a + 16 > 15 + b
a + 1 > b
a > b - 1
Let's now recall that we're dealing with integers. Therefore the above can be rewritten as:
a >= b.
This is the condition for getting carry flag = 1 after adding a
and (16)-b
. If the inequality doesn't hold, we get carry = 0.
Let's now recall that we were interested in overflow/underflow from subtraction (a - b). That condition is a < b.
Well, a >= b is the exact opposite of a < b.
From this it follows that the carry
flag that you get from adding a
and (16)-b
is the inverse of the subtraction overflow, or, in other words, the inverse of the borrow
flag you'd get by subtracting b
directly from a
using the appropriate subtraction instruction (e.g. SUB).
Just invert the carry or treat it in the opposite way.