skip to Main Content

We can read about Right shift operator >> on MDN

… the sign of the resulting number is the same as the sign of the first operand.

However, 3332508426 >> 24 === -58 in my Chrome 127.0.6533.120.

How that could be explained?

By the way, 3332508426 is decimal representation of IP 198.162.11.10.

4

Answers


  1. Javascript bit manipulation works with 32-bit signed integers.

    1<<31 for example gives -2147483648

    Numeric values however use floating point double precision (64 bit IEEE754), so there is no problem in writing for example

    x = 2147483648

    and if you display x you get 2147483648 (integers are represented without loss of accuracy up to ∓2⁵³ = ∓9007199254740992 … much more than 32 bit).

    For example however just shifting x by ZERO places you get -2147483648

    x << 0 returns -2147483648

    because the computation is done using 32-bit signed integers.

    Login or Signup to reply.
  2. 3332508426 is HEX C6A20B0A.
    If that is interpreted as 32 bit integer, the MSB is 1 so it is negative.
    Right shifting keeps the sign.

    Login or Signup to reply.
  3. MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift#description

    The >> operator is overloaded for two types of operands: number and BigInt. For numbers, the operator returns a 32-bit integer.

    As 3332508426 is already a 32-bit integer, it uses that value. However, 32-bit numbers are signed and the 32-bit binary representation of your number’s left-most bit is a 1, so is a negative value.

    9 (base 10): 00000000000000000000000000001001 (base 2)
    -9 (base 10): 11111111111111111111111111110111 (base 2)

    The solution is to convert your number to BigInt first, then convert back, ie:

    let result = Number(BigInt(3332508426) >> BigInt(24));
    
    console.log(result);
    console.log(Number((BigInt(3332508426) >> BigInt(16)) % BigInt(1<<8)))
    console.log(Number((BigInt(3332508426) >> BigInt(8)) % BigInt(1<<8)))
    console.log(Number(BigInt(3332508426) % BigInt(1<<8)))
    Login or Signup to reply.
  4. Others have explained why it’s negative, but if your just after extracting the bytes from a Uint32,..

    Another option, instead of bit shifting, if you want to extract the bytes from a Uint32, make a UInt32Array with the single value, and then cast that into a Uint8Array to extract the bytes.

    eg.

    const a = new Uint8Array(new Uint32Array([3332508426]).buffer);
    console.log(`${a[3]}.${a[2]}.${a[1]}.${a[0]}`);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search