Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is ~5 === -6 in JavaScript? [duplicate]

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.

like image 714
papiro Avatar asked May 12 '16 23:05

papiro


3 Answers

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
like image 100
Spencer Wieczorek Avatar answered Oct 18 '22 09:10

Spencer Wieczorek


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 ~ )

like image 30
pepperjack Avatar answered Oct 18 '22 09:10

pepperjack


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.

like image 38
Bikonja Avatar answered Oct 18 '22 10:10

Bikonja