7

I have binary form for -3 in two's complement form - 11111111111111111111111111111101, and use it with parseInt function:

parseInt('11111111111111111111111111111101', 2)

But it returns 4294967293, which is the integer that results if 11111111111111111111111111111101 is parsed as unsigned int. How can I parse integer as a signed one?

Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • Related (almost duplicate): http://stackoverflow.com/a/13468626/1207195 – Adriano Repetti May 04 '16 at 08:36
  • 1
    @AdrianoRepetti, I've seen that answer, and it doesn't answer my questions – Max Koretskyi May 04 '16 at 08:36
  • Why not? It's for base 16 and you need base 2, that's the only difference, as far as I can see... – Adriano Repetti May 04 '16 at 08:37
  • what is the number you are expecting? I think I found something, but am not sure – Tschallacka May 04 '16 at 08:37
  • Yeah, to my surprise, I'm not seeing a previous "how do I parse a two's complement string" question (for JavaScript). – T.J. Crowder May 04 '16 at 08:38
  • You provide a 32 Bit String to the ParseInt function. But If javascript interprets integers as 64 Bit values then, you need 64 bits. Could you try it please. I mean prepend you string with 16 x "1" – Peter Paul Kiefer May 04 '16 at 08:38
  • 1
    @PeterPaulKiefer: Nowhere in the JavaScript specification does it talk about treating anything as a 64-bit integer (well, there's a brief mention of *allowing* a 64-bit int intermediate result during a time clip operation). JavaScript deals primarily with IEEE-754 double-precision floating point values, and for bit manipulation (and a couple of other things) deals with 32-bit integer values (signed or unsigned depending on what it's doing). – T.J. Crowder May 04 '16 at 08:40
  • @T.J.Crowder, so there is no way to tell parseInt to treat a binary number as two's complement? – Max Koretskyi May 04 '16 at 08:43
  • @Maximus: Not as far as I know. – T.J. Crowder May 04 '16 at 08:43
  • 1
    Why is this being downvoted? I guess initially it was a bit unfocussed, but parsing a two's complement string to a number is a reasonable thing to need to do, and doesn't appear to have been asked and answered on-site yet. – T.J. Crowder May 04 '16 at 08:44
  • 2
    I looked into a ECMA Script 6 implementation (Mozilla) and saw that they treat a binary string as an unsigned string. You can not use 2-complements. But you can prepend it with a minus sign. i.e Build a bitweise complement of your string prpend it with a "-" and parse it. – Peter Paul Kiefer May 04 '16 at 08:48

3 Answers3

8
~~parseInt('11111111111111111111111111111101',2)// == -3

is what you are looking for.

Related answer ~~ vs-parseint

var x = ~~y; is a 'trick' (similar to var x = y << 0;) that (ab)uses the unary bitwise NOT operator to force the result to be in the range of a signed 32-bit integer, discarding any non-integer portion.

FZs
  • 16,581
  • 13
  • 41
  • 50
Tschallacka
  • 27,901
  • 14
  • 88
  • 133
1

i had the same problem, you can use the following:

function parseInt2complement(bitstring,bitcount)
{
    value = parseInt(bitstring, 2);

    if ((value & (1<<(bitcount-1))) > 0) {
       value = value - (1<<(bitcount));
    }
    return value;
}

console.log(parseInt2complement('111111111111111111111111111101', 30))
console.log(parseInt2complement('1111111111111111111111111111101', 31))
MatSch
  • 163
  • 6
0

For 32-bit numbers, it's enough to cast it to a 32-bit integer (no need for parseInt here), which can be done by applying any bitwise operation to it (and indicating that it's in binary by prefixing with 0b).

function parse(num){
  return ('0b'+num) | 0
}

console.log(parse('11111111111111111111111111111101'))

For a non-32-bit number, however, you'll need some tricks:

function parse(num, length = num.length){
  if(num[num.length-length] !== '1')
    return +('0b'+num)
  let inverse = ''
  for(const digit of num.slice(-length))
    inverse += +!+digit
  return -('0b' + inverse) - 1
}

console.log(parse('1101', 4)) //-3
console.log(parse('1111111111111101', 16)) //-3
console.log(parse('1111111111111111111111111111111111111111111111111111111111111101', 64)) //-3
console.log(parse('1111111111111111111111111111111111111111111111111111111111111101')) //-3, bit length inferred from the length of the string
FZs
  • 16,581
  • 13
  • 41
  • 50