I am creating a bitmask in javascript. It works fine for bit 0 through 14. When I set only bit fifteen to 1. It yields the integer value of “-2147483648” instead of “2147483648“. I can do a special case hack here by returning hardcoded “2147483648” for bit fifteen but I would like to know the correct way of doing it.
Sample code:
function join_bitmap(hex_lower_word, hex_upper_word)
{
var lower_word = parseInt(hex_lower_word, 16);
var upper_word = parseInt(hex_upper_word, 16);
return (0x00000000ffffffff & ((upper_word<<16) | lower_word));
}
Above code returns -2147483648 when hex_lower_word is “0x0” and hex_upper_word is “0x8000” instead of 2147483648
As previous answers explained, the bitwise operators are 32 bit signed. Thus, if at any point along the way you set bit 31, things will go badly wrong.
In your code, the expression
is evaluated first because of the parentheses, and since upper_word has the top bit set, you will now have a negative number (
0x80000000 = -2147483648)The solution is to make sure that you do not shift a
1into bit 31 – so you have to set bit 15 of the upper word to zero before shifting:This will take care of “numbers that are too big become negative”, but it won’t solve the problem completely – it will just give the wrong answer! To get back to the right answer, you need to set bit 31 in the answer, iff bit 15 was set in upper_word:
The rewritten function then becomes:
There isn’t just a single “hard coded special case” – there are 2 billion or so. This takes care of all of them.