benathon
benathon

Reputation: 7633

Left shift results in negative numbers in Javascript

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.

Upvotes: 14

Views: 4396

Answers (2)

Felix Kling
Felix Kling

Reputation: 816730

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.

Upvotes: 23

GregL
GregL

Reputation: 38131

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.

Upvotes: 3

Related Questions