Search code examples
javascripttypescriptbinarybitwise-operatorsbit-shift

How do I account for signed issues in binary bitshifts using TypeScript? (2^31 >> n)


I am making a checkers program that uses 32-bit binary ints to represent pieces on the board. To calculate possible moves, I apply bitshifts to the integers, but this doesn't work for the final bit.

This 32nd bit is set as present by adding 2^31 to the int (2147483648), but my issue is that when I apply a right bitshift to this value I get a negative number.

const test = 0b1000_0000_0000_0000_0000_0000_1000_0000;

console.log(test) //2147483776
console.log(test >> 0) //-2147483520

console.log(test >> 5) //-67108860
// expected output: 67108868

console.log(toBinary(test >> 5)) //1111_1100_0000_0000_0000_0000_0000_0100
//expected output: 0000_0100_0000_0000_0000_0000_0000_0100

I think this issue is to do with a limit for signed integers, is there a way I could set this as an unsigned integer to fix the problem? Or is there something else I can do to fix this?


Solution

  • You're looking for unsigned right shift (aka zero-fill right shift), >>>. Instead of extending the sign bit, it shifts zeros in. Example:

    const test = 0b1000_0000_0000_0000_0000_0000_1000_0000;
    
    console.log(test);        // 2147483776
    console.log(test >>> 0);  // -2147483520
    
    console.log(test >>> 5);  // 67108868
    
    console.log(toBinary(test));
    // => 1000_0000_0000_0000_0000_0000_1000_0000
    console.log(toBinary(test >>> 5));
    // => 0000_0100_0000_0000_0000_0000_0000_0100
    
    function toBinary(value) {
        const str = value.toString(2).padStart(32, "0");
        return str.replace(/(\d{4})/g, "_$1").substring(1);
    }