Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 97e4f5f

Browse files
sergiitktrekhleb
authored andcommittedApr 3, 2019
Add Full Adder algorithm (math/bits) (trekhleb#334)
* Add Full Adder algorithm (math/bits) * Full adder: minor spelling fixes * Full adder: even better comments
1 parent 339ae02 commit 97e4f5f

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed
 

‎src/algorithms/math/bits/README.md

+36
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,42 @@ Number: 9 = (10 - 1) = 0b01001
226226

227227
> See [isPowerOfTwo.js](isPowerOfTwo.js) for further details.
228228
229+
230+
#### Full Adder
231+
232+
This method adds up two integer numbers using bitwise operators.
233+
234+
It implements [full adder](https://en.wikipedia.org/wiki/Adder_(electronics))
235+
electronics circut logic to sum two 32-bit integers in two's complement format.
236+
It's using the boolean logic to cover all possible cases of adding two input bits:
237+
with and without a "carry bit" from adding the previous less-significant stage.
238+
239+
Legend:
240+
- `A`: Number `A`
241+
- `B`: Number `B`
242+
- `ai`: ith bit of number `A`
243+
- `bi`: ith bit of number `B`
244+
- `carryIn`: a bit carried in from the previous less-significant stage
245+
- `carryOut`: a bit to carry to the next most-significant stage
246+
- `bitSum`: The sum of `ai`, `bi`, and `carryIn`
247+
- `resultBin`: The full result of adding current stage with all less-significant stages (in binary)
248+
- `resultBin`: The full result of adding current stage with all less-significant stages (in decimal)
249+
```
250+
A = 3: 011
251+
B = 6: 110
252+
┌──────┬────┬────┬─────────┬──────────┬─────────┬───────────┬───────────┐
253+
│ bit │ ai │ bi │ carryIn │ carryOut │ bitSum │ resultBin │ resultDec │
254+
├──────┼────┼────┼─────────┼──────────┼─────────┼───────────┼───────────┤
255+
│ 0 │ 1 │ 0 │ 0 │ 0 │ 1 │ 1 │ 1 │
256+
│ 1 │ 1 │ 1 │ 0 │ 1 │ 0 │ 01 │ 1 │
257+
│ 2 │ 0 │ 1 │ 1 │ 1 │ 0 │ 001 │ 1 │
258+
│ 3 │ 0 │ 0 │ 1 │ 0 │ 1 │ 1001 │ 9 │
259+
└──────┴────┴────┴─────────┴──────────┴─────────┴───────────┴───────────┘
260+
```
261+
262+
> See [fullAdder.js](fullAdder.js) for further details.
263+
> See [Full Adder on YouTube](https://www.youtube.com/watch?v=wvJc9CZcvBc).
264+
229265
## References
230266

231267
- [Bit Manipulation on YouTube](https://www.youtube.com/watch?v=NLKQEOgBAnw&t=0s&index=28&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import fullAdder from '../fullAdder';
2+
3+
describe('Full adder', () => {
4+
it('should add up two numbers', () => {
5+
expect(fullAdder(0, 0)).toBe(0);
6+
expect(fullAdder(2, 0)).toBe(2);
7+
expect(fullAdder(0, 2)).toBe(2);
8+
expect(fullAdder(1, 2)).toBe(3);
9+
expect(fullAdder(2, 1)).toBe(3);
10+
expect(fullAdder(6, 6)).toBe(12);
11+
expect(fullAdder(-2, 4)).toBe(2);
12+
expect(fullAdder(4, -2)).toBe(2);
13+
expect(fullAdder(-4, -4)).toBe(-8);
14+
expect(fullAdder(4, -5)).toBe(-1);
15+
expect(fullAdder(2, 121)).toBe(123);
16+
expect(fullAdder(121, 2)).toBe(123);
17+
});
18+
});

‎src/algorithms/math/bits/fullAdder.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import getBit from './getBit';
2+
3+
/**
4+
* Add two numbers using only binary operators.
5+
*
6+
* This is an implementation of full adders logic circut.
7+
* https://en.wikipedia.org/wiki/Adder_(electronics)
8+
* Inspired by: https://www.youtube.com/watch?v=wvJc9CZcvBc
9+
*
10+
* Table(1)
11+
* INPUT | OUT
12+
* C Ai Bi | C Si | Row
13+
* -------- | -----| ---
14+
* 0 0 0 | 0 0 | 1
15+
* 0 0 1 | 0 1 | 2
16+
* 0 1 0 | 0 1 | 3
17+
* 0 1 1 | 1 0 | 4
18+
* -------- | ---- | --
19+
* 1 0 0 | 0 1 | 5
20+
* 1 0 1 | 1 0 | 6
21+
* 1 1 0 | 1 0 | 7
22+
* 1 1 1 | 1 1 | 8
23+
* ---------------------
24+
*
25+
* Legend:
26+
* INPUT C = Carry in, from the previous less-significant stage
27+
* INPUT Ai = ith bit of Number A
28+
* INPUT Bi = ith bit of Number B
29+
* OUT C = Carry out to the next most-significant stage
30+
* OUT Si = Bit Sum, ith least significant bit of the result
31+
*
32+
*
33+
* @param {number} a
34+
* @param {number} b
35+
* @return {number}
36+
*/
37+
export default function fullAdder(a, b) {
38+
let result = 0;
39+
let carry = 0;
40+
41+
// The operands of all bitwise operators are converted to signed
42+
// 32-bit integers in two's complement format.
43+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Signed_32-bit_integers
44+
for (let i = 0; i < 32; i += 1) {
45+
const ai = getBit(a, i);
46+
const bi = getBit(b, i);
47+
const carryIn = carry;
48+
49+
// Calculate binary Ai + Bi without carry (half adder)
50+
// See Table(1) rows 1 - 4: Si = Ai ^ Bi
51+
const aiPlusBi = ai ^ bi;
52+
53+
// Calculate ith bit of the result by adding the carry bit to Ai + Bi
54+
// For Table(1) rows 5 - 8 carryIn = 1: Si = Ai ^ Bi ^ 1, flip the bit
55+
// Fpr Table(1) rows 1 - 4 carryIn = 0: Si = Ai ^ Bi ^ 0, a no-op.
56+
const bitSum = aiPlusBi ^ carryIn;
57+
58+
// Carry out one to the next most-significant stage
59+
// when at least one of these is true:
60+
// 1) Table(1) rows 6, 7: one of Ai OR Bi is 1 AND carryIn = 1
61+
// 2) Table(1) rows 4, 8: Both Ai AND Bi are 1
62+
const carryOut = (aiPlusBi & carryIn) | (ai & bi);
63+
carry = carryOut;
64+
65+
// Set ith least significant bit of the result to bitSum.
66+
result |= bitSum << i;
67+
}
68+
return result;
69+
}

0 commit comments

Comments
 (0)
Please sign in to comment.