I am implementing decoding of BER-compressed integers and recently I’ve found a weird JavaScript behavior related to bitwise operations with big integers.
E.g.:
var a = 17516032; // has 25 bits
alert(a << 7) // outputs -2052915200
alert(a * 128) // outputs 2242052096
alert(2242052096 >> 16) // outputs -31325
alert(2242052096 / 65536) // outputs 34211
While the first workaround (multiplication instead of left shift) is acceptable, the second isn’t.
Why it happens? How to bear with it?
17516032in binary is00000001000010110100011000000000. Shifting to the left by 7 gives you10000101101000110000000000000000. This is equal to-2052915200in two’s complement (which is how almost all computers represent negative numbers).>>is a signed right shift. That means that the leftmost bit (which determines the sign of a number) will be shifted into the left side.e.g.
If you want to do an unsigned shift (which ignores the sign bit), use
>>>which will zero-fill the left end of the bitstring.