According to subsection 11.4.8 of the ECMAScript 5.1 standard:
The production UnaryExpression : ~ UnaryExpression is evaluated as follows:
- Let
expr
be the result of evaluating UnaryExpression.- Let
oldValue
beToInt32(GetValue(expr))
.- Return the result of applying bitwise plement to
oldValue
. The result is a signed 32-bit integer.
The ~
operator will invoke the internal method ToInt32
. In my understanding ToInt32(1)
and ToInt32(-1)
will return the same value 1 , but why does ~-1
equal 0 and ~1
equal -2?
Now my question is why ToInt32(-1)
equals -1?
subsection 9.5 of the ECMAScript 5.1 standard:
The abstract operation ToInt32 converts its argument to one of 232 integer values in the range −231 through 231−1, inclusive. This abstract operation functions as follows:
- Let number be the result of calling ToNumber on the input argument.
- If number is NaN, +0, −0, +∞, or −∞, return +0.
- Let posInt be sign(number) * floor(abs(number)).
- Let int32bit be posInt modulo 232; that is, a finite integer value k of Number type with positive sign and less than 232 in magnitude such that the mathematical difference of posInt and k is mathematically an integer multiple of 232.
- If int32bit is greater than or equal to 231, return int32bit − 232, otherwise return int32bit.
when the argument is -1,according to 9.5, in step 1 number will still be -1, skip step2 in step 3 posInt will be -1 in step 4 int32bit will be 1 in step 5 it will return 1
which step is wrong?
According to subsection 11.4.8 of the ECMAScript 5.1 standard:
The production UnaryExpression : ~ UnaryExpression is evaluated as follows:
- Let
expr
be the result of evaluating UnaryExpression.- Let
oldValue
beToInt32(GetValue(expr))
.- Return the result of applying bitwise plement to
oldValue
. The result is a signed 32-bit integer.
The ~
operator will invoke the internal method ToInt32
. In my understanding ToInt32(1)
and ToInt32(-1)
will return the same value 1 , but why does ~-1
equal 0 and ~1
equal -2?
Now my question is why ToInt32(-1)
equals -1?
subsection 9.5 of the ECMAScript 5.1 standard:
The abstract operation ToInt32 converts its argument to one of 232 integer values in the range −231 through 231−1, inclusive. This abstract operation functions as follows:
- Let number be the result of calling ToNumber on the input argument.
- If number is NaN, +0, −0, +∞, or −∞, return +0.
- Let posInt be sign(number) * floor(abs(number)).
- Let int32bit be posInt modulo 232; that is, a finite integer value k of Number type with positive sign and less than 232 in magnitude such that the mathematical difference of posInt and k is mathematically an integer multiple of 232.
- If int32bit is greater than or equal to 231, return int32bit − 232, otherwise return int32bit.
when the argument is -1,according to 9.5, in step 1 number will still be -1, skip step2 in step 3 posInt will be -1 in step 4 int32bit will be 1 in step 5 it will return 1
which step is wrong?
Share Improve this question edited Aug 15, 2013 at 17:38 Ted Hopp 235k48 gold badges411 silver badges532 bronze badges asked Aug 15, 2013 at 17:03 user1039304user1039304 4656 silver badges10 bronze badges 4- 1 ToIn32(-1) should yield -1 according to ecma-international/ecma-262/5.1/#sec-9.5 – BartoszKP Commented Aug 15, 2013 at 17:06
- Your understanding is wrong and was corrected in your previous question... (more specifically, in my answer) – Esailija Commented Aug 15, 2013 at 17:22
- possible duplicate of what is the result of 'x modulo y'? – Esailija Commented Aug 15, 2013 at 17:23
-
Found this helpful when looking up information about tilde. javascriptturnsmeon./the-tilde-operator-in-javascript. Basically
~x === -(x + 1)
– awbergs Commented Aug 15, 2013 at 17:27
3 Answers
Reset to default 17The -1
in 32-bit integer
1111 1111 1111 1111 1111 1111 1111 1111
So ~-1
will be
0000 0000 0000 0000 0000 0000 0000 0000
Which is zero.
The 1
in 32-bit integer
0000 0000 0000 0000 0000 0000 0000 0001
So ~1
will be
1111 1111 1111 1111 1111 1111 1111 1110
Which is -2
.
You should read about two's plement to understand the display of negative integer in binary-base.
Where did you get the idea that ToInt32(-1)
evaluates to 1? It evaluates to -1, which in 32-bit, two's plement binary representation, is all bits set to 1. When you apply the ~
operator, every bit then bees 0, which is the representation of 0 in 32-bit, two's plement binary.
The representation of 1 is all bits 0 except for bit 0. When the bits are inverted, the result is all bits 1 except for bit 0. This happens to be the two's plement representation of -2. (To see this, just subtract 1 from the two's plement representation of -1.)
ToInt32(1)
will return1
ToInt32(-1)
will return-1
-1
is represented as a signed 32-bit integer by having all 32 bits set. The bitwise plement of that is all bits clear, thus~-1
yields0
1
is represented as a signed 32-bit integer by having all bits clear except the bottom bit. The bitwise plement of that has all bits set except the bottom bit, which is the signed 32-bit integer representation of the value-2
. Thus,~1
yields-2