【问题标题】:Parsing of binary twos-complement number to decimal?将二进制补码数解析为十进制?
【发布时间】:2018-12-14 17:32:30
【问题描述】:

好吧,我很困惑,这并不比我想象的要容易...我想将二进制补码字符串转换为适当的数字:

-5 = '11111011' 根据Wikipedia

所以我认为以下会返回负 5,但事实并非如此。阅读维基百科后,似乎我所要做的就是减去一个然后反转位:

~(parseInt('11111011', 2) - 1)

但它返回 -251。令人困惑...

请注意,我将处理许多奇数位长度,并且不会都是 8 位。

【问题讨论】:

标签: javascript encoding binary type-conversion


【解决方案1】:

这将采用一个未知的位模式 = 8 带有前导 1,则为负符号整数。

诀窍是在 parseInt 之前填充到 32

const getSigned = binStr => parseInt(binStr.length >= 8 && binStr[0] === "1" ?
  binStr.padStart(32, "1") : binStr.padStart(32, "0"), 2) >> 0;

const signed = [
  "11111011",     // -5
  "01111011",     // 123
  "1111111111000" // -8
].map(getSigned);

console.log(signed);

【讨论】:

    【解决方案2】:

    经过一段时间的研究,我创建了这个解决方案......如果您对二进制和按位运算有经验,请告诉我您的想法:

    function getSignedInteger(bits) {
        let negative = (bits[0] === '1');
        if (negative) {
            let inverse = '';
            for (let i = 0; i < bits.length; i++) {
                inverse += (bits[i] === '0' ? '1' : '0');
            }
            return (parseInt(inverse, 2) + 1) * -1;
        } else {
            return parseInt(bits, 2);
        }
    }
    

    getSignedInteger('11111011') 返回 -5

    【讨论】:

      【解决方案3】:

      我感觉到你的困惑。维基百科文章向您展示了 8 位数字的示例,但您通常不会在 javascript 中处理 8 位数字。如果您想在 javascript 中探索二进制数数学,您可能会使用 32 位并通过位运算符强制对话到 32 位整数。

      所以翻译维基百科文章会给你这个:

      -5 看起来更像11111111111111111111111111111011

      所有这些额外的零都会被翻转。考虑到这一点,这更有意义:

      let str = "11111111111111111111111111111011"
      console.log(str.length, 'bits')
      console.log((parseInt(str, 2) >> 0))

      现在应该更有意义了:

      let five = '00000000000000000000000000000101'
      let neg6 = '11111111111111111111111111111010'
      
      console.log('5: ', parseInt(five, 2) >> 0)
      console.log('-6: ', parseInt(neg6, 2) >> 0)
      
      // two complement
      let neg6Plus1 = '11111111111111111111111111111011'
      
      console.log('-5: ', parseInt(neg6Plus1, 2) >> 0)

      【讨论】:

      • 您对此有何看法? parseInt('11111011'.padStart(32,'1'), 2) >> 0
      • @wayofthefuture 给了我预期的结果。
      • @wayofthefuture - 是的,它有助于制作所有 32 位。两个伟大的思想;)
      猜你喜欢
      • 2013-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-01
      • 2014-11-15
      • 1970-01-01
      • 2012-11-02
      • 2016-05-24
      相关资源
      最近更新 更多