Why is there "2 << -1" zero in javascript instead of one?

I came across this rather strange behavior of a bitwise shift-left operator, and I would like to better understand it ...

Let's say we want to build a function that receives an integer and returns the associated integer power of two, i.e.

power => Math.pow(2, power)

A more efficient way to do this would be to use a left-shift bitwise operator (let's say overflow is not a problem):

power => 1 << power

And it works great. It is strange that this should work too:

power => 2 << (power-1)

because it follows from:

  • 2 == 1 << 1 (bit coding 2)
  • (a << b) << c == a << (b + c) (semantics << )

However, this is not so because:

2 << -1 == 0

So, the second law fails:

0 == 2 << -1 == (1 << 1) << -1 ! = 1 << (1 + -1) == 1 << 0 == 1

At first I thought it was a problem switching to negative numbers, maybe js interpreted any shift with a negative number as zero? However, this is also not the case, because, for example:

1 << -31 == 2

As expected. And what's more:

2 << 31 == 2 << -1 == 0

So ... what's going on here? Testing all the shift values ​​for 2 , all of them give the expected value, with the exception of numbers coinciding with -1 mod 32, even positive ones that give zero instead of one.

Does anyone know why this is happening?

+5
source share
1 answer

It is very simple, all you need to do is follow the steps defined by the ecmascript standard:

Ecmascript <<Operator

Accordingly, when you do 2 <-1:

  • -1 is passed to uniged int 32, which means 4294967295 (-1 →> 0)
  • only the 5 least significant bits are considered: 4294967295 and 0x1F = 31
  • 2 <31 gives us 0
+2
source

Source: https://habr.com/ru/post/1276256/


All Articles