Search code examples
javascriptbinary-operators

Why am I getting this binary shift error?


I have a large number:

 let v = 204391396381585;

It is below the max safe int size of 2^53.

I do a binary shift:

v >>= 6;

I am expecting the result:

v === 3193615568462

ie a whole number which is the original v but divided by 2^6

Instead I get:

v === -28160434

Can anyone tell me what might be going wrong? Obviously it is something to do with the negative bit of a number, but can anyone tell me more?


Solution

  • The bitwise operators for the number type always convert the number to a 32-bit signed integer before performing the operation. Any bits beyond those that fit in a 32 bit signed integer are discarded. This applies even if the code is running on a 64-bit CPU.

    There are multiple ways around this, but the easiest is to not use the javascript number type, but rather bigints. BigInt is fairly well but not universally supported (no BigInt in Internet Explorer or other browsers more than a few years old). So you could do it like this:

    let v = 204391396381585n;
    v >>= 6n
    

    If dealing with bigints throughout your code is too much hassle, you can create a function that handles the conversions.

    let v = 204391396381585;
    v = bitShift(v,-6);
    
    function bitShift(value,shift) {
        return (shift > 0) ? Number(BigInt(value) << BigInt(shift)) 
            : Number(BigInt(value) >> BigInt(-shift));
    }