将二进制补码数解析为十进制?

问题描述 投票:0回答:4

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

-5 = '11111011' 根据 维基百科

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

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

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

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

javascript encoding binary type-conversion
4个回答
1
投票

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

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


1
投票

这将采用未知的位模式 <= 32 bits and if it is < 8 bits convert to positive int and if >= 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);


0
投票

我感觉到你的困惑。维基百科文章向您展示了 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)


0
投票

这对于将存储在数字(如 251 (11111011))而不是字符串(如“11111011”)中的补码转换为数字更有用。 这适用于任何小于 4294967295 的值(又名 0xffffffff、又名 11111111111111111111111111111111、又名 32 位最大无符号整数值-that-you-dont-want-want-hit-or-you-have-a-big -problem®) (输入的补码,而不是输出数字。)

// 32 bits of ones ( The max value that can be used with bitwise operators without bigInts)
const allOnes = 0xffffffff;
// The amount of bits is required to find the value of the "first bit" because the values are stored as 32 bit values
function decodeTwosComplement(value, bits) {
  // Just pad the value with 1s
  return value & (1 << (bits - 1) !== 0) ?
    (allOnes << bits) | value :
    value;
}
function decodeTwosComplementFromString(value) {
  return decodeTwosComplement(parseInt(value, 2), value.length);
}
console.log("11111011(-5):", decodeTwosComplementFromString("11111011"));
console.log("001011100(92):", decodeTwosComplementFromString("001011100"));
console.log("11111011(-5, from number):", decodeTwosComplement(0b11111011,8));
console.log("001011100(92, from number):", decodeTwosComplement(0b001011100,9));

© www.soinside.com 2019 - 2024. All rights reserved.