At the heart of computer performance lies binary multiplication, the process of combining numbers bit-by-bit.
Let's take a look at how it works.
1st principles of binary multiplication
To break it down, here you have the three logical operations used in binary multiplication, AND, SHIFT, ADD.
- AND: takes each bit of B in isolation and applies AND on the entire string of A bit-by-bit.
- SHIFT: Shift Left is performed every move down starting from 0, till all moves (based on the range of B) are performed.
- ADD: is used to add up the whole and get the product Sum in return.
For each bit of B (index i) we perform a move down, every move down is a Shift Left (starting at index 0) which creates a partial. Every partial is summed up using addition logic to get the multiplication end product.
Let me walk you through an example using 5 X 10 (0101 X 1010) starting at figure 1.0.
- A is 0101 (5)
- B is 1010 (10)
Bit position | B[i] | (B[i] AND A) | Shift (<< i) | Partial product (7b) |
---|---|---|---|---|
0 | 0 | 0000 | << 0 | XXX0000 |
1 | 1 | 0101 | << 1 | XX01010 |
2 | 0 | 0000 | << 2 | X000000 |
3 | 1 | 0101 | << 3 | 0101000 |
We mark unused positions with X which act as placeholders, in actual hardware these become 0s in register. So that the ALU can work with the same range in every bit-by-bit addition calculation, to get Sum and Carry out.
If you're not familiar with binary addition check out binary part-I.
Now let's apply binary addition row-by-row on each partial product.
Binary addition applied on Partial product
Short recap of Sum, and Carry out:
- Sum: A XOR B XOR Carry in
- Carry out: (A AND B) OR (Carry in AND (A XOR B))
Example: 1 + 1 with carry-in 0 gives sum = 0, carry = 1
Starting bit-by-bit at Partial 0, and 1 in figure 1.1, to get the Sum column then we repeat that process two more times.
Bit position | Running sum | Next partial | Carry in | Sum | Carry out |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 1 | 0 | 1 | 0 |
2 | 0 | 0 | 0 | 0 | 0 |
3 | 0 | 1 | 0 | 1 | 0 |
4 | 0 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 | 0 |
6 | 0 | 0 | 0 | 0 | 0 |
NOTE: Bit 0 is rightmost least significant bit (LSB) moving to leftmost most significant bit (MSB).
Now in figure 1.2 we take Sum from figure 1.0 and apply addition logic bit-by-bit with Partial 2 of figure 1.0.
Bit position | Running sum | Next partial | Carry in | Sum | Carry out |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 0 | 1 | 0 |
2 | 0 | 0 | 0 | 0 | 0 |
3 | 1 | 0 | 0 | 1 | 0 |
4 | 0 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 | 0 |
6 | 0 | 0 | 0 | 0 | 0 |
Arriving at the last Partial, Partial 3 in figure 1.0, we repeat addition logic for Sum and Carry out one last time.
Bit position | Running sum | Next partial | Carry in | Sum | Carry out |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 0 | 1 | 0 |
2 | 0 | 0 | 0 | 0 | 0 |
3 | 1 | 1 | 0 | 0 | 1 |
4 | 0 | 0 | 1 | 1 | 0 |
5 | 0 | 1 | 0 | 1 | 0 |
6 | 0 | 0 | 0 | 0 | 0 |
After applying addition logic on all four arrays we end up with '0110010' (you can read it in the Sum column), which is integer 50.
That was binary multiplication.
Like to stay updated and learn about Systems, Rust, Math, and more? Then you can follow me on X/Twitter where I'll be posting when a blog goes live.
Want to see coded examples? Click ALU a 32-bit Arithmetic Logic Unit that goes from integers to bit-by-bit simulations through logic gates, supports ADD, SUB, MULTIPLY, DIV.
Now go practice some binary multiplication till next time.