Reputation: 2115
I have two inputs in binary, and I'm returning the addition result in binary as well.
var addBinary = function(a, b) {
var dec = Number(parseInt(a, 2)) + Number(parseInt(b, 2));
return dec.toString(2);
};
For some insanely big binary like
a = 10100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101
b = 110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011
I'm outputting
110111101100010011000101110110100000011101000101011000000000000000000000000000000000000000000000000
where the supposed correct output is
110111101100010011000101110110100000011101000101011001000011011000001100011110011010010011000000000
Is it because of overflow? If so, what are the restrictions in Javascript for binary addition overflow? Sorry for the bunch of 1's and 0's.
Upvotes: 23
Views: 43619
Reputation: 11
var addBinary = function(a, b) {
return (BigInt("0b" + a) + BigInt("0b" + b)).toString(2);
};
Here, BigInt("0b" + a) and BigInt("0b" + b) directly convert the binary strings a and b to BigInt, using the "0b" notation to indicate that they are binary numbers.
This will print the right answer in all cases.
Upvotes: 1
Reputation: 17428
Inspired by @thepatriot, I created a one-liner version using the BigInt
object.
var addBinary = (a, b) => {
return (BigInt(`0b${a}`) + BigInt(`0b${b}`)).toString(2);
};
console.log(addBinary('10100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101','110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011'));
Upvotes: 9
Reputation: 31
var addBinary = function(a, b) {
let res = ""
let carry = 0
while(a || b || carry){
let temp = +a.slice(-1) + +b.slice(-1) + carry
res = temp%2 + res
carry = temp>1 ? 1 : 0
a = a.slice(0,-1)
b = b.slice(0,-1)
}
return res
}
Try this code
Upvotes: 0
Reputation: 130245
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.
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";
Upvotes: 11
Reputation: 103
parseInt
is possible to cause a problem that bigger than a max integer.
The solution is BigInt
.
(BigInt('0b' + a) + BigInt('0b' + b)).toString(2);
almost similar to
(parseInt(a, 2) + parseInt(b, 2)).toString(2)
but it can handle more.
Upvotes: 2
Reputation: 2206
You can Solve it like Below:
let addBinary = (a,b)=> parseInt(a,2)*parseInt(b,2).toString(2);
That's it
Upvotes: -1
Reputation: 79
just convert to int and convert again to bin
var addBinary = (a, b) => {
var dec = Number(parseInt(a, 2)) + Number(parseInt(b, 2));
return (dec >>> 0).toString(2);
};
console.log(addBinary(1000,11));
Upvotes: 0
Reputation: 41
instead of dealing with binary, we can convert them to decimal numbers and perform any arithmetic operation then convert back to binary again.
function calculateBinary(expr){
let [pre,post]=expr.split(/[+|\-|\*|\/]/).map(binary=>parseInt(parseInt(binary, 2).toString(10).trim()));
let sign=expr.match(/[+|\-|\*|\/]/)[0];
let res=eval(pre+sign+post);
return res.toString(2);
}
console.log(calculateBinary('11011+1000'))//=>100011
console.log(calculateBinary('1000-0100'))//=>100
console.log(calculateBinary('1000/0100'))//=>10
console.log(calculateBinary('10*10'))//=>100
Upvotes: 4
Reputation: 21
I would like to propose the top most shortness variant in ES6 (the main requirements was to "avoid using built-in big integers to solve this challenge"):
// It's my challenge solution with 104 chars only:
addBinaryStrings = ([...a], [...b]) => {
c = 0
r = ''
while (a[0] | b[0] | c) {
c += ~~a.pop() + ~~b.pop()
r = c%2 + r
c = c > 1
}
return r
}
// Test:
binaryString1 = "1010110000000001101011001000010110101111110010100011011100101010000101011010001110011001011110111"
binaryString2 = "10100110100001100010010001111100001110100110111001100001011010011000101111001110100011101110000100100010001100110000001010011000100110"
string1.innerText = binaryString1;
string2.innerText = binaryString2;
expected.innerText = "10100110100001100010010001111100001111111100111001101110110011011011100101001100111000001001101001110010111000000001111101100100011101"
result.innerText = addBinaryStrings(binaryString1, binaryString2)
* {
font-family: monospace;
}
div b {
color: red;
}
div span {
color: dodgerblue;
}
<div>BINARY 1: <b id="string1"></b></div>
<div>SUMM : <span>+</span></div>
<div>BINARY 2: <b id="string2"></b></div>
<div>FINALLY : <span>=</span></div>
<div>EXPECTED: <span id="expected"></span></div>
<div>RESULT : <span id="result"></span></div>
Upvotes: 0
Reputation:
This is my solution, using a couple of conditional statements.
function addBinary(a, b) {
let result = "";
let i = a.length - 1;
let j = b.length - 1;
let carry = 0;
while (i >= 0 || j >= 0 || carry > 0) {
const x = parseInt(a[i], 10) || 0;
const y = parseInt(b[j], 10) || 0;
const z = x + y + carry;
i--, j--;
// error handling: non-binary number
if (z > 3 || z < 0) return console.error("non-binary number");
result = z === 3 || z === 1 ? 1 + result : 0 + result;
carry = z < 2 ? 0 : 1;
}
return result;
}
The logic of the conditional statements is the same as using the following switch/case:
switch (z) {
case 3:
result = 1 + result;
carry = 1;
continue;
case 2:
result = 0 + result;
carry = 1;
continue;
case 1:
result = 1 + result;
carry = 0;
continue;
case 0:
result = 0 + result;
carry = 0;
continue;
default:
return console.error("non-binary number");
}
Upvotes: 1
Reputation: 1610
I would like to add my solution as well
let a = '1111';
let b = '1111';
let addBinary = (a, b) => {
let highestNumber;
let lowestNumber;
let answer = '';
let carry = 0;
let aArr = a.split('');
let bArr = b.split('');
if(aArr.length > bArr.length) {
highestNumber = aArr;
lowestNumber = bArr;
} else {
highestNumber = bArr;
lowestNumber = aArr;
}
let diff = highestNumber.length - lowestNumber.length;
let startingInd = highestNumber.length - diff;
for(let i= startingInd; i < highestNumber.length; i++) {
lowestNumber = ['0'].concat(lowestNumber);
}
for(let i=highestNumber.length-1; i >= 0; i--) {
let num1 = parseInt(highestNumber[i]);
let num2 = parseInt(lowestNumber[i]);
let sum = num1 + num2 + carry;
let currValue = sum === 1 || sum === 3 ? '1' : '0';
answer = currValue.concat(answer);
if(sum === 3 || sum === 2) carry = 1;
}
if(carry == 1) answer = '1'.concat(answer);
if(carry == 2) answer = '10'.concat(answer);
return answer;
};
console.log(addBinary(a, b));
Upvotes: 0
Reputation: 23
This is my try ... Nothing fancy simple logic.
var addBinary = function(a, b) {
let aLast = a.length - 1;
let bLast = b.length - 1;
let carry = 0;
let aStr = [];
while(aLast>=0 || bLast>=0){
let sum = carry;
if(aLast >= 0) {
sum+= Number(a[aLast]);
aLast--;
}
if(bLast >= 0) {
sum+= Number(b[bLast]);
bLast--
}
aStr.push(sum%2);
carry = Math.floor(sum/2);
}
if(carry) aStr.push(carry);
return aStr.reverse().join("");
};
Upvotes: 0
Reputation: 1927
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;
}
Upvotes: 4
Reputation: 1
Simple and Naive solution for adding 2 n-length binary integers:
function binaryAddition(num1, num2) {
let result = [];
let carry = 0;
for(let i = num1.length-1; i >= 0; i--) {
if((num1[i] === 1 && num2[i] === 1)) {
if(carry) {
result.unshift(1)
} else {
result.unshift(0);
}
carry = 1;
} else if((num1[i] === 0 && num2[i] === 0)) {
if(carry) {
result.unshift(1)
} else {
result.unshift(0);
}
carry = 0;
} else if((num1[i] === 1 && num2[i] === 0) || (num1[i] === 0 && num2[i] === 1)) {
if(carry) {
result.unshift(0)
carry = 1;
} else {
result.unshift(1);
}
}
}
if(carry) result.unshift(1);
return result;
}
Upvotes: -1
Reputation: 4865
Here is a simple solution, given a
and b
are two binary strings, return their sum
also in binary string.
let addBinary = (a, b) => {
// handle corner cases when either input is empty
if (a === null || a.length === 0) return b;
if (b === null || b.length === 0) return a;
let i = a.length - 1;
let j = b.length - 1;
let carry = 0;
let sum = '';
while (i >=0 || j >= 0) {
let x = i < 0 ? 0 : +a[i];
let y = j < 0 ? 0 : +b[i];
let val = x + y + carry;
carry = val > 1 ? 1 : 0;
sum = val % 2 + sum;
i--;
j--;
}
return carry > 0 ? carry + sum : sum;
};
Some basic rules in regards to binary addition:
Hopefully this can be helpful!
Upvotes: -1
Reputation: 1101
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;
};
Upvotes: 5
Reputation: 336
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!
Upvotes: 29
Reputation: 39
Just in my opinion,it is because those nums are too large to lose precision.
var addBinary = function(a, b) {
var dec = Number(parseInt(a, 2)) + Number(parseInt(b, 2));
console.log("the number a is " + parseInt(a, 2));
console.log("the number b is " + parseInt(b, 2));
console.log("the dec is " + dec);
return dec.toString(2);
};
var a = "10100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101"
var b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"
console.log(addBinary(a, b));
the result is
the number a is 2.484789315402498e+28
the number b is 5.2670055459872975e+29
the dec is 5.515484477527547e+29
110111101100010011000101110110100000011101000101011000000000000000000000000000000000000000000000000
You can see the numa and numb both loss precision.If converting the last result to binary:
parseInt("110111101100010011000101110110100000011101000101011000000000000000000000000000000000000000000000000", 2)
then you get :
5.515484477527547e+29.
so the process of "toString(2)" is right.
we manually simulate the process of the binary to solve this problem(suppose the input string is right, so I don't catch any exception in my code. The runtime environment is nodejs v4.6.0):
"use strict"
let addBinarybyChainhelen = function(a, b) {
let alen = a.length;
let blen = b.length;
let i = alen - 1;
let j = blen - 1;
let result = "";
let carry = 0;
while(i >= 0 && j >= 0) {
let acur = parseInt(a[i], 10);
let bcur = parseInt(b[j], 10);
let rcur = (acur + bcur + carry) % 2;
carry = parseInt((acur + bcur + carry) / 2);
result += rcur;
i--;
j--;
}
while(i >= 0) {
let acur = parseInt(a[i], 10);
let rcur = (acur + carry) % 2;
carry = parseInt((acur + carry) / 2);
result += rcur;
i--;
}
while(j >= 0) {
let bcur = parseInt(b[j], 10);
let rcur = (bcur + carry) % 2;
carry = parseInt((bcur + carry) / 2);
result += rcur;
j--;
}
if(carry) {
result += carry;
}
return result.split("").reverse().join("");
}
// use the function
let a = "10100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101"
let b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"
console.log(addBinarybyChainhelen(a, b))
and get supposed correct output
110111101100010011000101110110100000011101000101011001000011011000001100011110011010010011000000000
Upvotes: 3