Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add Full Adder algorithm (math/bits) #334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/algorithms/math/bits/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,42 @@ Number: 9 = (10 - 1) = 0b01001

> See [isPowerOfTwo.js](isPowerOfTwo.js) for further details.


#### Full Adder

This method adds up two integer numbers using bitwise operators.

It implements [full adder](https://en.wikipedia.org/wiki/Adder_(electronics))
electronics circut logic to sum two 32-bit integers in two's complement format.
It's using the boolean logic to cover all possible cases of adding two input bits:
with and without a "carry bit" from adding the previous less-significant stage.

Legend:
- `A`: Number `A`
- `B`: Number `B`
- `ai`: ith bit of number `A`
- `bi`: ith bit of number `B`
- `carryIn`: a bit carried in from the previous less-significant stage
- `carryOut`: a bit to carry to the next most-significant stage
- `bitSum`: The sum of `ai`, `bi`, and `carryIn`
- `resultBin`: The full result of adding current stage with all less-significant stages (in binary)
- `resultBin`: The full result of adding current stage with all less-significant stages (in decimal)
```
A = 3: 011
B = 6: 110
┌──────┬────┬────┬─────────┬──────────┬─────────┬───────────┬───────────┐
│ bit │ ai │ bi │ carryIn │ carryOut │ bitSum │ resultBin │ resultDec │
├──────┼────┼────┼─────────┼──────────┼─────────┼───────────┼───────────┤
│ 0 │ 1 │ 0 │ 0 │ 0 │ 1 │ 1 │ 1 │
│ 1 │ 1 │ 1 │ 0 │ 1 │ 0 │ 01 │ 1 │
│ 2 │ 0 │ 1 │ 1 │ 1 │ 0 │ 001 │ 1 │
│ 3 │ 0 │ 0 │ 1 │ 0 │ 1 │ 1001 │ 9 │
└──────┴────┴────┴─────────┴──────────┴─────────┴───────────┴───────────┘
```

> See [fullAdder.js](fullAdder.js) for further details.
> See [Full Adder on YouTube](https://www.youtube.com/watch?v=wvJc9CZcvBc).

## References

- [Bit Manipulation on YouTube](https://www.youtube.com/watch?v=NLKQEOgBAnw&t=0s&index=28&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
Expand Down
18 changes: 18 additions & 0 deletions src/algorithms/math/bits/__test__/fullAdder.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import fullAdder from '../fullAdder';

describe('Full adder', () => {
it('should add up two numbers', () => {
expect(fullAdder(0, 0)).toBe(0);
expect(fullAdder(2, 0)).toBe(2);
expect(fullAdder(0, 2)).toBe(2);
expect(fullAdder(1, 2)).toBe(3);
expect(fullAdder(2, 1)).toBe(3);
expect(fullAdder(6, 6)).toBe(12);
expect(fullAdder(-2, 4)).toBe(2);
expect(fullAdder(4, -2)).toBe(2);
expect(fullAdder(-4, -4)).toBe(-8);
expect(fullAdder(4, -5)).toBe(-1);
expect(fullAdder(2, 121)).toBe(123);
expect(fullAdder(121, 2)).toBe(123);
});
});
69 changes: 69 additions & 0 deletions src/algorithms/math/bits/fullAdder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import getBit from './getBit';

/**
* Add two numbers using only binary operators.
*
* This is an implementation of full adders logic circut.
* https://en.wikipedia.org/wiki/Adder_(electronics)
* Inspired by: https://www.youtube.com/watch?v=wvJc9CZcvBc
*
* Table(1)
* INPUT | OUT
* C Ai Bi | C Si | Row
* -------- | -----| ---
* 0 0 0 | 0 0 | 1
* 0 0 1 | 0 1 | 2
* 0 1 0 | 0 1 | 3
* 0 1 1 | 1 0 | 4
* -------- | ---- | --
* 1 0 0 | 0 1 | 5
* 1 0 1 | 1 0 | 6
* 1 1 0 | 1 0 | 7
* 1 1 1 | 1 1 | 8
* ---------------------
*
* Legend:
* INPUT C = Carry in, from the previous less-significant stage
* INPUT Ai = ith bit of Number A
* INPUT Bi = ith bit of Number B
* OUT C = Carry out to the next most-significant stage
* OUT Si = Bit Sum, ith least significant bit of the result
*
*
* @param {number} a
* @param {number} b
* @return {number}
*/
export default function fullAdder(a, b) {
let result = 0;
let carry = 0;

// The operands of all bitwise operators are converted to signed
// 32-bit integers in two's complement format.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Signed_32-bit_integers
for (let i = 0; i < 32; i += 1) {
const ai = getBit(a, i);
const bi = getBit(b, i);
const carryIn = carry;

// Calculate binary Ai + Bi without carry (half adder)
// See Table(1) rows 1 - 4: Si = Ai ^ Bi
const aiPlusBi = ai ^ bi;

// Calculate ith bit of the result by adding the carry bit to Ai + Bi
// For Table(1) rows 5 - 8 carryIn = 1: Si = Ai ^ Bi ^ 1, flip the bit
// Fpr Table(1) rows 1 - 4 carryIn = 0: Si = Ai ^ Bi ^ 0, a no-op.
const bitSum = aiPlusBi ^ carryIn;

// Carry out one to the next most-significant stage
// when at least one of these is true:
// 1) Table(1) rows 6, 7: one of Ai OR Bi is 1 AND carryIn = 1
// 2) Table(1) rows 4, 8: Both Ai AND Bi are 1
const carryOut = (aiPlusBi & carryIn) | (ai & bi);
carry = carryOut;

// Set ith least significant bit of the result to bitSum.
result |= bitSum << i;
}
return result;
}