【问题标题】:How to convert binary string to decimal?如何将二进制字符串转换为十进制?
【发布时间】:2012-05-02 18:47:11
【问题描述】:

我想将二进制字符串转换为数字 例如

var binary = "1101000" // code for 104
var digit = binary.toString(10); // Convert String or Digit (But it does not work !)
console.log(digit);

这怎么可能? 谢谢

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    @baptx@Jon@ikhvjs 的 cmets 的基础上,以下内容应该适用于非常大的二进制字符串:

    // ES10+
    function bin2dec(binStr) {
        const lastIndex = binStr.length - 1;
    
        return Array.from(binStr).reduceRight((total, currValue, index) => (
            (currValue === '1') ? total + (BigInt(2) ** BigInt(lastIndex - index)) : total
        ), BigInt(0));
    }
    

    或者,同样使用for 循环:

    // ES10+
    function bin2dec(binStr) {
        const lastIndex = binStr.length - 1;
        let total = BigInt(0);
    
        for (let i = 0; i < binStr.length; i++) {
            if (binStr[lastIndex - i] === '1') {
                total += (BigInt(2) ** BigInt(i));
            }
        }
    
        return total;
    }
    

    例如:

    console.log(bin2dec('101')); // 5n
    
    console.log(bin2dec('110101')); // 53n
    
    console.log(bin2dec('11111111111111111111111111111111111111111111111111111')); // 9007199254740991n
    
    console.log(bin2dec('101110110001101000111100001110001000101000101011001100000011101')); // 6741077324010461213n
    

    为希望了解更多信息的人写了一封blog post

    【讨论】:

      【解决方案2】:

      我收集了所有其他人的建议并创建了以下函数,该函数具有 3 个参数,即该数字来自的数字和基数以及该数字将要使用的基数:

      changeBase(1101000, 2, 10) => 104
      

      运行代码片段自己尝试一下:

      function changeBase(number, fromBase, toBase) {
          if (fromBase == 10)
              return (parseInt(number)).toString(toBase)
          else if (toBase == 10)
              return parseInt(number, fromBase);
          else {
              var numberInDecimal = parseInt(number, fromBase);
              return parseInt(numberInDecimal).toString(toBase);
          }
      }
      
      $("#btnConvert").click(function(){
          var number = $("#txtNumber").val(),
          fromBase = $("#txtFromBase").val(),
          toBase = $("#txtToBase").val();
          $("#lblResult").text(changeBase(number, fromBase, toBase));
      });
      #lblResult {
        padding: 20px;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <input id="txtNumber" type="text" placeholder="Number" />
      <input id="txtFromBase" type="text" placeholder="From Base" />
      <input id="txtToBase" type="text" placeholder="To Base" />
      <input id="btnConvert" type="button" value="Convert" />
      <span id="lblResult"></span>
      
      <p>Examples: <br />
        <em>110, 2, 10</em> => <em>6</em>; (110)<sub>2</sub> = 6<br />
      
        <em>2d, 16, 10</em> => <em>45</em>; (2d)<sub>16</sub> = 45<br />
        <em>45, 10, 16</em> => <em>2d</em>; 45 = (2d)<sub>16</sub><br />
        <em>101101, 2, 16</em> => <em>2d</em>; (101101)<sub>2</sub> = (2d)<sub>16</sub>
      </p>

      仅供参考:如果您想将 2d 作为十六进制数字传递,则需要将其作为字符串发送,如下所示: changeBase('2d', 16, 10)

      【讨论】:

      • 不处理浮点数。 3.14159265,10,16 给出 3
      【解决方案3】:
      var num = 10;
      
      alert("Binary " + num.toString(2));   // 1010
      alert("Octal " + num.toString(8));    // 12
      alert("Hex " + num.toString(16));     // a
      
      alert("Binary to Decimal " + parseInt("1010", 2));  // 10
      alert("Octal to Decimal " + parseInt("12", 8));     // 10
      alert("Hex to Decimal " + parseInt("a", 16));       // 10
      

      【讨论】:

        【解决方案4】:

        利用更多 ES6 语法和自动功能对传统二进制转换算法进行了轻微修改:

        1. 将二进制序列字符串转换为数组(假设它还没有 作为数组传递)

        2. 逆序强制 0 索引从最右边的二进制开始 数字作为二进制是从右向左计算的

        3. 'reduce'数组函数遍历数组,执行求和 (2^index) 每个二进制数字 [仅当二进制数字 === 1] (0 数字 总是产生 0)

        注意:二进制转换公式:

        {其中d=二进制数字,i=数组索引,n=数组长度-1(从右开始)}

        n
        ∑ (d * 2^i)
        我=0

        let decimal = Array.from(binaryString).reverse().reduce((total, val, index)=>val==="1"?total + 2**index:total, 0);  
        
        console.log(`Converted BINARY sequence (${binaryString}) to DECIMAL (${decimal}).`);
        

        【讨论】:

          【解决方案5】:
          function binaryToDecimal(string) {
              let decimal = +0;
              let bits = +1;
              for(let i = 0; i < string.length; i++) {
                  let currNum = +(string[string.length - i - 1]);
                  if(currNum === 1) {
                      decimal += bits;
                  }
                  bits *= 2;
              }
              console.log(decimal);
          }
          

          【讨论】:

            【解决方案6】:

            另一种仅用于函数式 JS 练习的实现可能是

            var bin2int = s => Array.prototype.reduce.call(s, (p,c) => p*2 + +c)
            console.log(bin2int("101010"));
            其中+cString 类型c 强制为Number 类型值以进行正确添加。

            【讨论】:

              【解决方案7】:

              ES6 支持binary numeric literals 整数,所以如果二进制字符串是不可变的,就像问题中的示例代码一样,可以直接输入前缀0b0B

              var binary = 0b1101000; // code for 104
              console.log(binary); // prints 104
              

              【讨论】:

                【解决方案8】:

                parseInt() 带有基数是最好的解决方案(正如许多人所说的那样):

                但是如果你想在没有 parseInt 的情况下实现它,这里有一个实现:

                  function bin2dec(num){
                    return num.split('').reverse().reduce(function(x, y, i){
                      return (y === '1') ? x + Math.pow(2, i) : x;
                    }, 0);
                  }
                

                【讨论】:

                • 现在有一个 reduceRight() 函数。你可能不再需要 reverse() 了。
                【解决方案9】:

                使用parseIntradix参数:

                var binary = "1101000";
                var digit = parseInt(binary, 2);
                console.log(digit);
                

                【讨论】:

                  【解决方案10】:

                  parseInt 函数将字符串转换为数字,它采用第二个参数指定字符串表示的基数:

                  var digit = parseInt(binary, 2);
                  

                  See it in action.

                  【讨论】:

                  • 这仍然相关吗? parseInt(101, 2) 返回5
                  • @srph:这并不奇怪,以 2 为底的 101 在以 10 为底的 5。
                  • 啊,我明白了。我一定误解了parseInt 的含义。我认为它会将字符串从基数 10 转换 -> 无论如何(像 parseInt('5612', 2) 一样思考会返回其二进制形式;)。
                  • @baptx 任何返回Number 的方法都会因如此高的值而失败(请参阅this question 和接受的答案)。检查今天的最新技术,您应该改用BigInt(得到广泛支持)。您可以通过将实现更改为显式使用BigInt 和求幂运算符** 而不是Math.pow 来直接适应Math.pow,它会起作用。
                  • @baptx 我做了一个小提琴here。我不认为这让我们说“扩展”值得包含在答案中。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-07-07
                  • 1970-01-01
                  • 2019-08-23
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多