11

Note: all of the following binary representations should be read right-to-left. I'm not sure why I think about them like that, but I actually didn't know that people also represent binary from left-to-right. Confusing!

On MDN's article for JavaScript's bitwise operators (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) it says that the ~ operator is the bitwise NOT operator.

On Wikipedia (https://en.wikipedia.org/wiki/Bitwise_operation#NOT) it says "The bitwise NOT, or complement, is a unary operation that performs logical negation on each bit, forming the ones' complement of the given binary value. Bits that are 0 become 1, and those that are 1 become 0."

Now, take the number 5 in binary: 0101

If I type ~5 in my browser console, I get -6 whose binary representation is 1110. I expected the negation to turn 0101 into 1010, which is actually 10 (or -2 if the leftmost digit is taken to be the sign).

All of the explanations I read of JavaScript's ~ operator says that it evaluates the number to -(x+1), but this doesn't explain to me logically what that operator is doing on a "bitwise" level.

Basically, 0101 becomes 1110.

What are the intermediate steps to witness this transformation? I see the leading bit becoming flipped, thus changing the sign. But that's about all I can gather.

papiro
  • 2,158
  • 1
  • 20
  • 29

4 Answers4

4

It does indeed perform a bit-wise NOT, the negative number is in two's complement. So the value 1010 is -6.

Two's complement basically works by the very left-most bit signifies a negative number and is taken as a negative value. All other 1 bits are added to this number. For example:

1010 => (-8 +0 +2 +0) => -6
1111 => (-8 +4 +2 +1) => -1
user2357112
  • 260,549
  • 28
  • 431
  • 505
Spencer Wieczorek
  • 21,229
  • 7
  • 44
  • 54
2

Why does bitwise "not 1" equal -2? is the same idea.
Cerebrus's answer in the above link (BINARY R -> L):
There are 2 integers between 1 and -2: 0 and -1

1 in binary is 00000000000000000000000000000001
0 in binary is 00000000000000000000000000000000
-1 in binary is 11111111111111111111111111111111
-2 in binary is 11111111111111111111111111111110
("binary" being 2's complement, in the case of a bitwise not ~ )

Community
  • 1
  • 1
pepperjack
  • 673
  • 6
  • 20
  • This I understand (I think). To me, a 1 would be `001` and a -2 would be `110` which is the 1 with its bits inverted. But simply inverting the bits doesn't appear to turn 5 into -6. – papiro May 13 '16 at 00:27
  • I see now my confusion! The leftmost bit is not merely for indicating the sign, but also counts for something in the negative. So `110` looked to me like negative-two-zero but actually is (-4)-2-0 which added all together is -2! Tricky tricky – papiro May 13 '16 at 00:39
2

You've come very close to the solution by realizing that the first bit is the sign, however, the rest of the bits aren't used 'as is'. In fact, in computing, signed numbers are represented by two's complement.

There are detailed articles on the concept on Wikipedia and various other websites, but in short, when the first bit is 1 (indicating a negative number), the rest of the bits make up a number that basically shows how much you add to the minimum number (e.g. in an 8-bit integer the minimum would be -256 which is 11111111 so inverting 5 (00000101) becomes 11111010 or 250, so you can get the decimal by adding the 250 to -256 and you get the -6). This explanation is a simplification for decimal systems, but for full understanding of how this works you should really read a whole article on two's complement.

Bikonja
  • 909
  • 5
  • 15
2

You are being confused by the sign bit and where it is placed....

Extend the number of bits (to for example a very short int of 8 bits) and see

00000110 6

Bit inversion ~

00000101 5
11111010 ~5 (bitwise inversion of 5)

And counting down from zero

00000000 0
11111111 -1
11111110 -2
11111101 -3
11111100 -4
11111011 -5
11111010 -6

So

11111010 -6

and

11111010 ~5

is the same.

This is true not only for JavaScript, but for anything which runs on a computer that is based on 2 complement number systems -- not sure if JavaScript has ever run on anything else :-)

user2357112
  • 260,549
  • 28
  • 431
  • 505
Soren
  • 14,402
  • 4
  • 41
  • 67