As the previous answers explained, bitwise operators are 32-bit. Thus, if you set bit 31 at any time along the way, everything will be bad.
In your code, the expression
(upper_word<<16) | lower_word)
evaluated first due to the brackets, and since upper_word has the upper bit, you will now have a negative number ( 0x80000000 = -2147483648 )
The solution is so that you do not move a 1 to bit 31 - therefore, before transferring you must set bit 15 of the upper word:
mask15 = 0x7fff; ((upper_word&mask15)<<16|lower_word)
This will make sure that “too large numbers become negative”, but this will not solve the problem completely - it will just give the wrong answer! To return to the correct answer, you need to set bit 31 in the answer if bit 15 was set to upper_word:
bit15 = 0x8000; bit31 = 0x80000000; answer = answer + (upper_word & bit15)?bit31:0;
Then the rewritten function becomes:
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); var mask15 = 0x7fff; var bit15 = 0x8000; var bit31 = 0x80000000; return 0xffffffff & (((upper_word&mask15)<<16) | lower_word) + ((upper_word & bit15)?bit31:0); }
There is not only one “hard-coded special case” - there are about 2 billion of them. It takes care of all of them.
source share