Javascript: Add two binary numbers (returning binary)
Here's my take on this:
The logic is simple, just like taught in elementary school, starting from the right-most digit: I add the first number's last digit and and second number's last digit, and keep the carry for next round.
On each round (inside the while
) I right-trim both numbers, so for example:
// number
1101 -> 110
// The math is simple: 1101/10|0 (divide by 10 and convert to integer)
Inputs & output are Strings to overcome JS maximum integer limitations, where a String's length can be much larger.
Full code:
function binaryAddition(a,b){
var result = "",
carry = 0
while(a || b || carry){
let sum = +a.slice(-1) + +b.slice(-1) + carry // get last digit from each number and sum
if( sum > 1 ){
result = sum%2 + result
carry = 1
}
else{
result = sum + result
carry = 0
}
// trim last digit (110 -> 11)
a = a.slice(0, -1)
b = b.slice(0, -1)
}
return result
}
// Tests
[
["0","0"],
["1","1"],
["1","0"],
["0","1"],
["10","1"],
["11","1"],
["10","10"],
["111","111"],
["1010","11"]
].forEach(numbers =>
document.write(
numbers[0] + " + " +
numbers[1] + " = " +
binaryAddition(numbers[0], numbers[1]) +
" <mark> (" +
parseInt(numbers[0], 2) + " + " +
parseInt(numbers[1], 2) + " = " +
parseInt(binaryAddition(numbers[0], numbers[1]),2) +
")</mark><br>"
)
)
document.body.style="font:16px monospace";
general solution that supports binary strings of different lengths
I've added a padZeroes()
function to Cassandra Wilcox's nice answer to create a general solution that supports binary strings of different lengths ð
I've tested this solution against the add binary problem on leetcode, so it should be pretty robust.
/**
* @param {string} a
* @param {string} b
* @return {string}
*/
// logic gates
function xor(a, b) {
return a === b ? 0 : 1;
}
function and(a, b) {
return a == 1 && b == 1 ? 1 : 0;
}
function or(a, b) {
return a || b;
}
function halfAdder(a, b) {
const sum = xor(a, b);
const carry = and(a, b);
return [sum, carry];
}
function fullAdder(a, b, carry) {
halfAdd = halfAdder(a, b);
const sum = xor(carry, halfAdd[0]);
carry = and(carry, halfAdd[0]);
carry = or(carry, halfAdd[1]);
return [sum, carry];
}
function padZeroes(a, b) {
const lengthDifference = a.length - b.length;
switch (lengthDifference) {
case 0:
break;
default:
const zeroes = Array.from(Array(Math.abs(lengthDifference)), () =>
String(0)
);
if (lengthDifference > 0) {
// if a is longer than b
// then we pad b with zeroes
b = `${zeroes.join('')}${b}`;
} else {
// if b is longer than a
// then we pad a with zeroes
a = `${zeroes.join('')}${a}`;
}
}
return [a, b];
}
function addBinary(a, b) {
let sum = '';
let carry = '';
const paddedInput = padZeroes(a, b);
a = paddedInput[0];
b = paddedInput[1];
for (let i = a.length - 1; i >= 0; i--) {
if (i == a.length - 1) {
// half add the first pair
const halfAdd1 = halfAdder(a[i], b[i]);
sum = halfAdd1[0] + sum;
carry = halfAdd1[1];
} else {
// full add the rest
const fullAdd = fullAdder(a[i], b[i], carry);
sum = fullAdd[0] + sum;
carry = fullAdd[1];
}
}
return carry ? carry + sum : sum;
}
I've developed a solution for binary addition in Javascript.
My initial goal was to solidify my understanding of binary logic by replicating the mechanisms used in digital binary adder circuits in Javascript (no base conversions or bitwise operators used).
You can find a working version of my original project on CodePen.
It's doing a lot more with the DOM than you probably need, but when I plugged in your numbers (with tweaks mentioned below), I was happy to see that it worked!
Working Solution Code << this project is modified from my original project and contains only the code needed to output the correct answer.
This solution assumes that a
and b
are strings of the same length. To use this solution your input variables should be modified to:
var a = "000010100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101"
var b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"
(I just filled in the missing digits at the front of var a
with zeros.)
As you can see, I recreated all of the components used in a physical implementation of a binary adder circuit:
Half Adder:
function halfAdder(a, b){
const sum = xor(a,b);
const carry = and(a,b);
return [sum, carry];
}
Full Adder:
function fullAdder(a, b, carry){
halfAdd = halfAdder(a,b);
const sum = xor(carry, halfAdd[0]);
carry = and(carry, halfAdd[0]);
carry = or(carry, halfAdd[1]);
return [sum, carry];
}
Logic Gates:
function xor(a, b){return (a === b ? 0 : 1);}
function and(a, b){return a == 1 && b == 1 ? 1 : 0;}
function or(a, b){return (a || b);}
Main Function:
function addBinary(a, b){
let sum = '';
let carry = '';
for(var i = a.length-1;i>=0; i--){
if(i == a.length-1){
//half add the first pair
const halfAdd1 = halfAdder(a[i],b[i]);
sum = halfAdd1[0]+sum;
carry = halfAdd1[1];
}else{
//full add the rest
const fullAdd = fullAdder(a[i],b[i],carry);
sum = fullAdd[0]+sum;
carry = fullAdd[1];
}
}
return carry ? carry + sum : sum;
}
So then, addBinary(a,b)
produces the correct answer!
var a = "000010100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101"
var b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"
var answer = "110111101100010011000101110110100000011101000101011001000011011000001100011110011010010011000000000";
console.log(addBinary(a, b) == answer); //true
I hope some of what I've done here can be useful to you too!
Forget about Javascript's precision of operating, think about how to plus one binary in math.
For example, 11
+ 10
.
First, we should start from right to left.
Now we get
1 + 0 = 1
After that, we move to next.
1 + 1 = 10
If we use Javascript, how to get the result.
We know that, Mod
can get the rest number, Division
can get the carry.
In the decimal system, we get 1 + 1 = 2
, how to transfer 2
to 10
.
We can use
result % 2 // we can get single digit
result / 2 | 0 // we can get tens digit, `| 0` can remove decimal.
Now we can just concat the two strings together.
BinaryNumber = result / 2 | 0 + result % 2 + '' // string concat
So our final code can be this:
/**
* @param {string} a
* @param {string} b
* @return {string}
*/
var addBinary = function(a, b) {
var i = a.length - 1;
var j = b.length - 1;
var carry = 0;
var result = "";
while(i >= 0 || j >= 0) {
var m = i < 0 ? 0 : a[i] | 0;
var n = j < 0 ? 0 : b[j] | 0;
carry += m + n; // sum of two digits
result = carry % 2 + result; // string concat
carry = carry / 2 | 0; // remove decimals, 1 / 2 = 0.5, only get 0
i--;
j--;
}
if(carry !== 0) {
result = carry + result;
}
return result;
};