Using bitwise operators in javascript

I am creating a bitmask in javascript. It works fine for bits from 0 to 14. When I set only bits from 15 to 1. This gives the integer value " -2147483648 " instead of " 2147483648 ". I can do a special random hack here by returning hardcoded " 2147483648 " for bit fifteen, but I would like to know the right way to do this.

Code example:

 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 the code, -2147483648 is returned when hex_lower_word is "0x0" and hex_upper_word is "0x8000" instead of 2147483648

+4
source share
3 answers

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.

+1
source

The reason for this is because Javascript bit changer operations use signed 32-bit integers. Therefore, if you do this:

 0x1 << 31 // sets the 15th bit of the high word 

It will set the sign bit to 1, which means negative.

On the other hand, instead of shifting the bits, you multiply by two arguments, you will get the desired result:

 1 * Math.pow(2, 31) 
+3
source

The reason is because you are installing sign bit ...

2147483648 is 1, followed by 31 zeros in binary format ...

Since you perform a bitwise action, the output is always a signed 32-bit number, which makes the 32nd bit a signed bit, so you get a negative number ...

Update

 (upper_word * Math.pow(2, 16)) 

will give a positive 2147483648 .

But you still have an OR operation that returns us to the square ...

+2
source

All Articles