Arith PDF
Arith PDF
Binary Arithmetic
e Arithmetic in binary is really no different than arithmetic in decimal, except
that we only have two legal digits instead of ten.
f In decimal, the operation looks something like this (with carries shown
in ‘()’ above each digit position):
(1)
5
7
1 2
If the sum of the digits in a column exceeds 9, we carry (in units of
powers of 10) into the next column.
f In binary, the operation looks something like this:
(1) (1) (1)
1 0 1
1 1 1
1 1 0 0
If the sum of the digits in a column exceeds 1, we carry (in units of
powers of 2) into the next column.
e The principles are identical: you add up the digits in the column, and you
get a sum digit and a carry digit. But since we’re in binary, the sum is 0 or
1, and the carry is 0 or 1.
1
Cmpt 150 Binary Arithmetic February, 2012
e How do we implement arithmetic? Just the way we’d implement any other
boolean function on 3 variables. (For addition, we’ve already done half the
work, as the example we used to learn K-map techniques.)
e The K-maps and boolean expressions for Σ (i) and co(i) are:
xy xy
ci 00 01 11 10 ci 00 01 11 10
0 0 1 0 1 0 0 0 1 0
1 1 0 1 0 1 0 1 1 1
Σ (i) = x(i) ⊕ y(i) ⊕ ci(i) co(i) = x(i) ⋅ y(i) + x(i) ⋅ ci(i) + y(i) ⋅ ci(i)
The K-map looks pretty hopeless
until you remember that this is
the pattern for XOR.
e The circuit for a full adder is:
2
Cmpt 150 Binary Arithmetic February, 2012
x(i)
y(i)
co(i)
ci(i)
Σ(i)
e This is well and good — we can add up two bits. But to make something
really useful, we’ll want numbers greater than 0 or 1. How do we go about
this?
e The full adder that we’ve made is just a single-bit slice of an n-bit adder. If
we tie the carry-out of stage i to the carry-in of stage i + 1, we can create an
adder for as many bits as we like.
e Suppose I rearrange the pieces of the full adder to make that a little more
convenient:
x(i) y(i)
co(i)
ci(i)
Σ(i)
3
Cmpt 150 Binary Arithmetic February, 2012
co(i+3) ci(i)
e Generally, we won’t keep the inner detail in view — the idea is to begin
creating a hierarchy of abstractions.
f Just as in programming, really. It’s analogous to creating a subroutine
in a programming language.
e The first step is to wrap up the full adder logic schematic in a box, showing
just the inputs and outputs, so that we have:
x y
FA
co ci
x y x y x y x y
FA FA FA FA
co(i+3) co ci co ci co ci co ci ci(i)
Σ Σ Σ Σ
e The final step is to take the four full adder components and reduce them to
a single component, representing a four-bit adder:
4 4
x(3:0) y(3:0)
co ci
adder
Σ(3:0)
4
Cmpt 150 Binary Arithmetic February, 2012
e So, now we can add two unsigned (positive) numbers. How do we extend
what we know to handle subtraction?
0 0 1 0 1 0 0 1 0 0
1 1 0 1 0 1 1 1 1 0
diff (i) = x(i) ⊕ y(i) ⊕ bi(i) bo(i) = x(i) ⋅ y(i) + x(i) ⋅ bi(i) + y(i) ⋅ bi(i)
e But now we have a problem — how do we know if the result is positive
or negative? And that begs the question, “How do we represent a negative
number?”
5
Cmpt 150 Binary Arithmetic February, 2012
6
Cmpt 150 Binary Arithmetic February, 2012
e So that this doesn’t come across as complete magic, let me give a simple
illustration in decimal, before I give you the rules in binary.
f The general idea here is something called the radix complement. For
decimal, that’d be 10’s complement.
f To form the 10’s complement of a number, you subtract the number
from the next higher power of 10. E.g., the 10’s complement of 209 is
1000 − 209 = 791.
For future reference, note that I could write −209 = −1000 + 791.
f Now, suppose I want to perform the subtraction 315 − 209. You’d agree
with me that 315 − 1000 + 1000 − 209 is an equivalent operation.
f So, I have 315 − 209 = 315 + 791 − 1000 = 1106 − 1000 = 106, which is
the correct answer.
e Right, you say. I’ve taken a relatively simple operation and doubled the work.
Trust me, it’ll look better in binary.
e The first thing we need to know is how to form the 2’s complement of a
binary number.
f It’s the same procedure, we subtract the number from the next higher
power of 2. E.g., to form the 2’s complement of 4310 = 1010112 , we
perform the subtraction 1000000 − 101011 = 010101.
f This isn’t too helpful, though, because it still involves subtraction. But,
suppose I make the following observation: 1000000 − 0000001 = 0111111,
and 1 − 0 = 1, 1 − 1 = 0, i.e., logical NOT.
So, if I perform ((1000000 − 1) − 101011) + 1 = ¬101011 + 1 = 010101, I
can see that the easy rule to form the two’s complement of a binary
number is “NOT(number) + 1”.
To repeat the previous example again, I can form the 2’s complement of
4310 as ¬101011 + 1 = 010100 + 1 = 010101.
e Now, for the big test — can I do subtraction in binary using two’s comple-
ment in the same way that I did in decimal with 10’s complement?
7
Cmpt 150 Binary Arithmetic February, 2012
e The answer is to explicitly include the power of two used to form the radix
complement as part of the representation of a binary number.
8
Cmpt 150 Binary Arithmetic February, 2012
−26 25 24 23 22 21 20
1 0 1 0 1 0 1
-64 +16 +4 +1
e What about range? Let’s explore the limits of what we can represent with 7
bits.
9
Cmpt 150 Binary Arithmetic February, 2012
f If the sign bit is 1, the number is negative (because the sum of all the
positively weighted bit positions cannot quite cancel the negative weight
on the most significant column). If the sign bit is 0, the number is
positive.
f With n bits, we can represent numbers from −2(n−1) to 2(n−1) − 1.
e Now, let’s come back to arithmetic, using the same two examples, 5010 −
4310 = 710 , and 5010 + 2110 = 7110 .
10
Cmpt 150 Binary Arithmetic February, 2012
−26 25 24 23 22 21 20
-50 1 0 0 1 1 1 0
-21 1 1 0 1 0 1 1
71 0 1 1 1 0 0 1
Here, we have no carry-in to the sign bit, but we do have a carry-out.
We really need to express 2 ∗ (−26 ) = −27 , and we need 8 bits to do that.
So this result, too, is invalid.
f And one final example: −43 − 21 = −64.
−26 25 24 23 22 21 20
-43 1 0 1 0 1 0 1
-21 1 1 0 1 0 1 1
-64 1 0 0 0 0 0 0
Here we seem to have a carry-in and a carry-out for the sign bit. But
don’t forget that the sign bit has a negative weight. What really hap-
pened is that we calculated (−26 ) + (−26 ) + (26 ) = −26 . This number is
perfectly legal, and we can ignore the carry-out from the msb.
f From this, we could calculate overflow using x(msb), y(msb), and ci(msb),
but usually we adopt a simpler rule, easy to remember.
f Look at the columns for ci(msb) and co(msb). Where they’re the same,
we have a valid result. Where they differ, we have overflow.
f Remembering that a 2-input XOR produces a 1 when the inputs differ,
we say ovf = ci(msb) ⊕ co(msb).
In english, “if there’s a carry-in and no carry-out, or carry-out and no
carry-in, then we have arithmetic overflow.”
11
Cmpt 150 Binary Arithmetic February, 2012
e Now we can design logic to do addition and subtraction, and keep it simple.
Let’s quickly review why.
add/sub
x y x y x y x y
FA FA FA FA
co(i+3) co ci co ci co ci co ci
Σ Σ Σ Σ
ovf
This circuit will add and subtract numbers in the range 10002 to 01112
(-8 to +7, or −2(4−1) to +2(4−1) − 1).
The add/sub signal controls whether the circuit adds or subtracts. When
it’s 1 (subtract), we form the 2’s complement of y(3:0), using the XORs
for logical negation and forcing a 1 at ci(0) to implement the +1.
The overflow is calculated as the XOR of the carry-in and carry-out of
the most significant bit.
f In two’s complement representation, only the msb (sign bit) has nega-
tive weight; all other bits have positive weight. This must hold for any
number of bits.
f Consider a four-bit value. The value will be b3 (−23 ) + b2 (22 ) + b1 (21 ) +
b0 (20 )
12
Cmpt 150 Binary Arithmetic February, 2012
13