Javascript:添加两个二进制数(返回二进制)

pat*_*g94 7 javascript binary numbers

我有两个二进制输入,我也在二进制中返回加法结果.

var addBinary = function(a, b) {
    var dec = Number(parseInt(a, 2)) + Number(parseInt(b, 2));
    return dec.toString(2);
};
Run Code Online (Sandbox Code Playgroud)

对于一些疯狂的大二进制像

a = 10100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101

b = 110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011

我正在输出

110111101100010011000101110110100000011101000101011000000000000000000000000000000000000000000000000

所谓正确输出的地方

110111101100010011000101110110100000011101000101011001000011011000001100011110011010010011000000000

是因为溢出?如果是这样,Javascript对二进制加法溢出的限制是什么?对不起一堆1和0.

小智 14

我在Javascript中开发了二进制加法解决方案.

我最初的目标是通过在Javascript中复制数字二进制加法器电路中使用的机制来巩固我对二进制逻辑的理解(没有使用基本转换或按位运算符).

您可以在CodePen上找到我原始项目的工作版本.

使用DOM做的事情比你可能需要的要多得多,但是当我插入你的数字时(通过下面提到的调整),我很高兴看到它有效!

工作解决方案代码 <<此项目是从我的原始项目修改而来,只包含输出正确答案所需的代码.

该解决方案假设a并且b是相同长度的字符串.要使用此解决方案,您的输入变量应修改为:

var a = "000010100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101"

var b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"
Run Code Online (Sandbox Code Playgroud)

(我只var a用零填充了前面缺少的数字.)

如您所见,我重新创建了二进制加法器电路的物理实现中使用的所有组件:

半加法器:

function halfAdder(a, b){
  const sum = xor(a,b);
  const carry = and(a,b);
  return [sum, carry];
}
Run Code Online (Sandbox Code Playgroud)

全加器:

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];
}
Run Code Online (Sandbox Code Playgroud)

逻辑门:

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);}
Run Code Online (Sandbox Code Playgroud)

主功能:

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;
}
Run Code Online (Sandbox Code Playgroud)

那么,addBinary(a,b)产生正确的答案!

var a = "000010100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101"
var b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"
var answer = "110111101100010011000101110110100000011101000101011001000011011000001100011110011010010011000000000";

console.log(addBinary(a, b) == answer); //true
Run Code Online (Sandbox Code Playgroud)

我希望我在这里所做的一些事情对你也有用!


Pen*_*Liu 8

受到@ thepatriot的启发,我使用该对象创建了一个单行版本BigInt

var addBinary = (a, b) => {
  return (BigInt(`0b${a}`) + BigInt(`0b${b}`)).toString(2);
};

console.log(addBinary('10100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101','110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011'));
Run Code Online (Sandbox Code Playgroud)


Hec*_*Guo 5

忘掉Javascript的运算精度,想想如何在数学中加一二进制。

例如,11+ 10

首先,我们应该从右向左开始。现在我们得到 1 + 0 = 1 了之后,我们进入下一步。 1 + 1 = 10 如果我们使用Javascript,如何得到结果。

我们知道,Mod能得到余数,Division就能得到进位。在十进制中,我们得到1 + 1 = 2,如何转变210。我们可以用

result % 2   // we can get single digit
result / 2 | 0   // we can get tens digit, `| 0` can remove decimal.
Run Code Online (Sandbox Code Playgroud)

现在我们可以将两个字符串连接在一起。

BinaryNumber = result / 2 | 0 + result % 2 + ''  // string concat
Run Code Online (Sandbox Code Playgroud)

所以我们最终的代码可以是这样的:

/**
 * @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;
};
Run Code Online (Sandbox Code Playgroud)


vsy*_*ync 5

这是我的看法:

逻辑很简单,就像在小学时一样,从最右边的数字开始:我将第一个数字的最后一位和第二个数字的最后一位相加,并保留下一轮的进位。

在每一轮中(while),我都对两个数字进行右修剪,例如:

// number
1101 -> 110
// The math is simple: 1101/10|0 (divide by 10 and convert to integer)
Run Code Online (Sandbox Code Playgroud)

输入和输出是String,可以克服JS最大整数限制,其中String的长度可能更大。

完整代码:

// number
1101 -> 110
// The math is simple: 1101/10|0 (divide by 10 and convert to integer)
Run Code Online (Sandbox Code Playgroud)

  • @DanielWilliams - 这是将 *String* 转换为 *Number* (整数)的“技巧”。如果在字符串**之前**应用数学运算,javascript 会将*表达式* 计算为数字 (3认同)
  • 你能解释一下“a.slice(-1)”前面的加号在这里的作用吗? (2认同)