Разбор двоичного числа с двойным дополнением до десятичного? - PullRequest
0 голосов
/ 06 июля 2018

Ну, я запутался, это не проще, чем я думал ... Я хочу преобразовать двоичную строку, дополняющую два, в соответствующее число:

-5 = '11111011' согласно Википедия

Так что я думаю, что следующее вернет отрицательный 5, но это не так. После прочтения Википедии кажется, что все, что мне нужно сделать, это вычесть один, а затем инвертировать биты:

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

Но он возвращает -251. Смешение ...

Обратите внимание, что я буду иметь дело со многими нечетными битами, и все они не будут 8 битами.

Ответы [ 3 ]

0 голосов
/ 06 июля 2018

Через некоторое время, работая над ним, я создал это решение ... если у вас есть опыт работы с двоичными и побитовыми операциями, пожалуйста, дайте мне знать ваши мысли:

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

0 голосов
/ 06 июля 2018

Я чувствую ваше замешательство. Статья в Википедии показывает вам примеры с 8-битными числами, но вы обычно не имеете дело с 8-битными числами в javascript. Если вы хотите изучить математику двоичных чисел в 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 голосов
/ 06 июля 2018

Это займет неизвестную битовую комбинацию <= 32 бита, и если она <8 бит, преобразуется в положительное значение int, а если> = 8 с ведущим 1, то значение со знаком минус.

Хитрость заключается в том, чтобы набрать 32 до parseInt

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

[
"11111011", // -5
"01111011", // 123
"1111111111000" // -8
].forEach(function(binStr) {
  let signed = getSigned(binStr)
  console.log(signed);
});
...