|
| 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