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