mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-26 07:01:18 +08:00
Add Full Adder algorithm (math/bits) (#334)
* Add Full Adder algorithm (math/bits) * Full adder: minor spelling fixes * Full adder: even better comments
This commit is contained in:
parent
339ae02977
commit
97e4f5fe2a
@ -226,6 +226,42 @@ Number: 9 = (10 - 1) = 0b01001
|
|||||||
|
|
||||||
> See [isPowerOfTwo.js](isPowerOfTwo.js) for further details.
|
> 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
|
## References
|
||||||
|
|
||||||
- [Bit Manipulation on YouTube](https://www.youtube.com/watch?v=NLKQEOgBAnw&t=0s&index=28&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
|
- [Bit Manipulation on YouTube](https://www.youtube.com/watch?v=NLKQEOgBAnw&t=0s&index=28&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
|
||||||
|
18
src/algorithms/math/bits/__test__/fullAdder.test.js
Normal file
18
src/algorithms/math/bits/__test__/fullAdder.test.js
Normal file
@ -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
src/algorithms/math/bits/fullAdder.js
Normal file
69
src/algorithms/math/bits/fullAdder.js
Normal file
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user