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

新手上路,请多包涵

我有两个二进制输入,我也以二进制返回加法结果。

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

对于一些非常大的二进制文件,比如

a = 10100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101

b = 110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011

我正在输出

110111101100010011000101110110100000011101000101011000000000000000000000000000000000000000000000000

假定的正确输出在哪里

110111101100010011000101110110100000011101000101011001000011011000001100011110011010010011000000000

是因为溢出了吗?如果是这样,Javascript 中对二进制加法溢出有哪些限制?对不起,一堆 1 和 0。

原文由 patrickhuang94 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 263
2 个回答

我开发了一个用 Javascript 进行二进制加法的解决方案。

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

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

它对 DOM 所做的工作比您可能需要的要多得多,但是当我输入您的数字时(通过下面提到的调整),我很高兴看到它起作用了!

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

此解决方案假定 ab 是相同长度的字符串。要使用此解决方案,您的输入变量应修改为:

 var a = "000010100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101"

var b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"

(我只是用零填充了 var a 前面缺失的数字。)

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

半加器:

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

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

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

console.log(addBinary(a, b) == answer); //true

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

原文由 Cassandra Wilcox 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是我对此的看法:

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

在每一轮(在 while 内)我右修剪两个数字,例如:

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

输入和输出是 字符串,以克服 JS 最大整数 限制,其中字符串的长度可以大得多。

完整代码:

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

原文由 vsync 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题