A thing which I noticed in Javascript -
a << -1
Returns 0 when a = even.
Returns -2147483648 when a = odd.
Similarly, different values are returned when -1
is changed to some other -ve
number.
Can someone explain what bit operations are taking place under the hood ? Or is the behavior undefined ?
Thanks
EDIT
Also shouldn't Zero-fill right shift i.e. -2 >>> 1
return 7
?
-2 = 1110. After, right shift with zero-fill, it should give 0111 = 7
but
a = -2; console.log(a >>> 1);
returns
2147483647
The LeftShift operator adds zeros to the right of the binary representation of a number, shifting the bits to the left. Only the 5 least significant digits of the additive expression are used. So:
The last expression returns 5 as shift only uses the last 5 bits of the the additive expression, which is 1000000 so only the 00000 part is used.
Got the answer to the second part of my question i.e.
-2 >>> 1 = 7
.Javascript always deals with 32 bits. So when I do
-2 >>> 1
, what really happens under the hood is -11111111111111111111111111111110 >>> 1
which gives01111111111111111111111111111111 = (2147483647)base10
I too wondered about this which is how I landed here. I’ve done a little research and figured out the behavior. Essentially JavaScript treats the operand and shift value as sequences of bits rather than as numbers. It works with 32 bit integers (floats get truncated) and the maximum shift is 32 bits. If we shift by a number greater than 32, all the bits would shift out, resulting in zero. To ensure the shift is less than or equal to 32, JavaScript truncates the 5 least significant bits [
a << (b&0x1F)
] or possibly with the modulus method [a << (b%32)
] which yields the same result.With that out of the way, think of the negative number you are shifting by as a sequence of bits, not a negative number (i.e. -1). In this case
b = -1 = 0xFFFFFFFF
. Since this number is larger than 32, it is truncated0xFFFFFFFF & 0x1F = 31
or0xFFFFFFFF % 32 = 31
.So in your example “a" gets shifted all the way from the least significant bit to the most significant bit (the sign bit). Therefor the result of the shift is either
0x00000000
or (0x80000000 = -2147483648
) depending on whether the operand had the 1 bit set (odd or even).