Reputation: 79
When I run this code here:
console.log(255<<24==0xff000000)
I get a false instead of true. Why is that?
Upvotes: 4
Views: 2556
Reputation: 724
Bitwise operations in javascript convert a number to a signed 32-bit integer, as described by T.J., so you only have 31 bits for safely comparing to a hex literal. If you want to preserve the unsigned number you really want (as opposed to casting your hex literal to the same negative number), do this:
255 * (1 << 24) == 0xff000000
Upvotes: 1
Reputation: 140228
0xff000000
doesn't specify bits of a 32-bit integer but a real number in hexadecimal base. For instance 0xff000000000000000000000
is 4.932417344027687e+27
All bitwise operations except >>>
give the operand int32 semantics, with >>>
giving uint32 semantics.
You may therefore use | 0
as a kind of int
declaration or (int)
cast:
255 << 24 == (0xff000000 | 0)
true
Upvotes: 1
Reputation: 13151
Look at it this way. This should look intuitive to you:
255<<24 == 0xff000000<<0 // Returns true
Bitwise operators work on integral numbers not on number types. Consider it as an equivalent to type casting as in other languages, where you happen to be putting a larger size number into smaller one & you lose stuff...
Javascript sacrifices precision to allow larger figures due to the floating point format, adopted.
So Javascript would lose the precision for 0xff000000, the same way as it did for 255.
Upvotes: 2
Reputation: 1074505
Because JavaScript numbers are IEEE-754 double-precision floating point, not 32-bit integers. So 0xff000000
is a large positive number (decimal 4,278,190,080), not a negative number as it would be if that were a signed 32-bit integer.
When you do <<
, the number being shifted (255 in your case) is temporarily converted to a signed 32-bit integer for the purposes of doing the bit shift:
00000000000000000000000011111111 ^\ / | \----- significant bits ----/ +------- sign bit
When we shift that 24 places left, a 1 bit ends up in the sign bit:
11111111000000000000000000000000 ^\ / | \----- significant bits ----/ +------- sign bit
...and so the result ends up being negative, and gets turned back into a negative IEEE-754 number (-16,777,216 decimal). -16,777,216 is not equal to 4,278,190,080.
(The range of IEEE-754 double-precision floats is larger than the range of 32-bit signed integers. I'm not quite sure why I feel that's relevant, but I do, so I guess I'll leave it in the answer...)
Upvotes: 5