# Javascript’s Shift right with zero-fill operator (>>>) yielding unexpected result

First, `(-1 >>> 0) === (2**32 - 1)` which I expect is due to adding a new zero to the left, thus converting the number into 33-bit number?

But, Why is `(-1 >>> 32) === (2**32 - 1)` as well, while I expect it (after shifting the 32-bit number 32 times and replacing the Most Significant Bits with zeros) to be 0.

Shouldn’t it be equal `((-1 >>> 31) >>> 1) === 0`? or Am I missing something?

When you execute `(-1 >>> 0)` you are executing an unsigned right shift. The unsigned here is key. Per the spec, the result of `>>>` is always unsigned. `-1` is represented as the two’s compliment of `1`. This in binary is all `1`s (In an 8 bit system it’d be `11111111`).

So now you are making it unsigned by executing `>>> 0`. You are saying, “shift the binary representation of `-1`, which is all `1`s, by zero bits (make no changes), but make it return an unsigned number.” So, you get the value of all `1`s. Go to any javascript console in a browser and type:

```console.log(2**32 - 1) //4294967295
// 0b means binary representation, and it can have a negative sign
console.log(0b11111111111111111111111111111111) //4294967295
console.log(-0b1 >>> 0) //4294967295
```

Remember `2 **` any number minus `1` is always all ones in binary. It’s the same number of ones as the power you raised two to. So `2**32 - 1` is 32 `1`s. For example, two to the 3rd power (eight) minus one (seven) is `111` in binary.

So for the next one `(-1 >>> 32) === (2**32 - 1)`…. let’s look at a few things. We know the binary representation of `-1` is all `1`s. Then shift it right one digit and you get the same value as having all `1`s but precede it with a zero (and return an unsigned number).

```console.log(-1 >>> 1) //2147483647
console.log(0b01111111111111111111111111111111) //2147483647
```

And keep shifting until you have 31 zeros and a single `1` at the end.

```console.log(-1 >>> 31) //1
```

This makes sense to me, we have 31 `0`s and a single `1` now for our 32 bits.

So then you hit the weird case, shifting one more time should make zero right?

Per the spec:

```6.1.6.1.11 Number::unsignedRightShift ( x, y )
Let lnum be ! ToInt32(x).
Let rnum be ! ToUint32(y).
Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
Return the result of performing a zero-filling right shift of lnum by shiftCount bits. Vacated bits are filled with zero. The result is an unsigned 32-bit integer.
```

So we know we already have `-1`, which is all `1`s in twos compliment. And we are going to shift it per the last step of the docs by `shiftCount` bits (which we think is 32). And `shiftCount` is:

Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.

So what is `rnum & 0x1F`? Well `&` means a bitwise `AND` operation. `lnum` is the number left of the `>>>` and `rnum` is the number right of it. So we are saying `32 AND 0x1F`. Remember 32 is `100000`. `0x` is hexadecimal where each character can be represented by `4` bits. `1` is `0001` and F is `1111`. So `0x1F` is `00011111` or `11111` (`31` in base 10, `2**5 - 1` also).

```console.log(0x1F) //31 (which is 11111)

32: 100000 &
0x1F: 011111
---------
000000
```

The number of bits to shift if zero. This is because the leading `1` in `32` is not part of the `5` most significant bits! `32` is six bits. So we take 32 `1`s and shift it zero bits! That’s why. The answer is still 32 `1`s.

On the example `-1 >>> 31` this made sense because 31 is `<= 5` bits. So we did

```  31: 11111 &
0x1F: 11111
-------
11111
```

And shifted it `31` bits…. as expected.

Let’s test this further…. let’s do

```console.log(-1 >>> 33) //2147483647
console.log(-1 >>> 1)  //2147483647
```

That makes sense, just shift it one bit.

```  33: 100001 &
0x1F: 011111
---------
00001
```

So, go over `5` bits with a bitwise operator and get confused. Want to play stump the dummy with a person who hasn’t researched the ECMAScript to answer a stackoverflow post? Just ask why are these the same.

```console.log(-1 >>> 24033) //2147483647
console.log(-1 >>> 1)     //2147483647
```

Well of course it’s because

```console.log(0b101110111100001) // 24033
console.log(0b000000000000001) // 1
//                      ^^^^^ I only care about these bits!!!
```