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 left shift and right shift operators should not be used for negative numbers. The result of is undefined behaviour if any of the operands is a negative number.
Negative shift counts are illegal and cause a ValueError to be raised. A left shift by n bits is equivalent to multiplication by pow(2, n). A long integer is returned if the result exceeds the range of plain integers.
The left shift operator ( << ) shifts the first operand the specified number of bits, modulo 32, to the left. Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right.
The number to the left of the operator is shifted the number of places specified by the number to the right. Each shift to the left doubles the number, therefore each left shift multiplies the original number by 2. Use the left shift for fast multiplication or to pack a group of numbers together into one larger number.
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 truncated 0xFFFFFFFF & 0x1F = 31
or 0xFFFFFFFF % 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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With