I'm having trouble understanding how shifting works. I would expect that a
and b
would be the same but that's not the case:
a = 0xff000000;
console.log(a.toString(16));
b = 0xff << 24;
console.log(b.toString(16));
resulting in:
ff000000
-1000000
I came to this code while trying to create a 32bit number from 4 bytes.
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. For example results of both 1 >> -1 and 1 << -1 is undefined. If the number is shifted more than the size of integer, the behaviour is undefined.
Operator >> called Signed right shift, shift all the bits to right a specified number of times. Important is >> fills leftmost sign bit (Most Significant Bit MSB) to leftmost bit the after shift. This is called sign extension and serves to preserve the sign of negative numbers when you shift them right.
Right Shifts For signed numbers, the sign bit is used to fill the vacated bit positions. In other words, if the number is positive, 0 is used, and if the number is negative, 1 is used. The result of a right-shift of a signed negative number is implementation-dependent.
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.
Bitwise operators convert their operands to signed 32 bit numbers. That means the most significant bit is the sign bit, which gives you only 31 bits for the number value.
0xff000000
by itself is interpreted as 64bit floating point value. But truncating this to a 32bit signed integer produces a negative value since the most significant bit is 1
:
0xff000000.toString(2);
> "11111111000000000000000000000000"
(0xff000000 | 0).toString(16)
> -1000000
According to Bitwise operations on 32-bit unsigned ints? you can use >>> 0
to convert the value back to an unsigned value:
0xff << 24 >>> 0
> 4278190080
From the spec:
The result is an unsigned 32-bit integer.
So it turns out this is as per the spec. Bit shift operators return signed, 32-bit integer results.
The result is a signed 32-bit integer.
From the latest ECMAScript spec.
Because your number is already 8 bits long, shifting it left by 24 bits and then interpreting that as a signed integer means that the leading 1
bit is seen as making it a negative number.
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