views:

289

answers:

4

I've never used the >> and << operators, not because I've never needed them, but because I don't know if I could have used them, or where I should have.

100 >> 3 outputs 12 instead of 12.5. Why is this. Perhaps learning where to best use right shift will answer that implicitly, but I'm curious.

+4  A: 

>> and << are the right and left bit shift operators, respectively. You should look at the binary representation of the numbers.

>>> bin(100)
'0b1100100'
>>> bin(12)
'0b1100'
Hank Gay
+12  A: 

First of all:

Right shift is not divide

Now, we look at what right-shift actually does, and it will become clear.

First, recall that a number is stored in memory as a collection of binary digits. For example, if we have 8 bits of memory, we can store 2 as 00000010 and 5 as 00000101.

Right-shift takes those digits and shifts them to the right - for example, right-shifting our above two digits by one will give 00000001 and 00000010.

Notice that the lowest digit is shifted off the end entirely and has no effect on the final result.

Anon.
Just to expand a little bit, 100 is represented in binary as 01100100, which when shifted right 3 digits is 00001100, which is 12.
StrixVaria
@Anon Thanks. I, needless to say, don't know much about how binary is constructed from literals (or vice versa), but I would assume it's not a coincidence that `2 << x` appears functionally equivalent to `2**x*2`. Can you expand on the math involved?
orokusaki
Sure. The first thing to note is that binary is constructed similarly to decimal, we just use a different base - so instead of ones, tens, hundreds, thousands, we use ones, twos, fours, eights and so on. Shifting bits to the left *appears* functionally equivalent to multiplication-by-two in the same way that tacking a zero on the end of a base 10 number *appears* functionally equivalent to multiplication-by-10.
Anon.
@orukusaki: To put it another way, your example can be redescribed as `y << x` being equivalent to `2**x * y`. The '2' is because the binary representation of computer numbers is base 2 and so each position gives you an extra power of 2. The decimal equivalent would be `10**x * y` - shift a '1' two digits to the left and you get '100', ie. 10**2 * 1.
Kylotan
@anon Thanks for that info. That's interesting.
orokusaki
A: 

Bit shifting an integer gives another integer. For instance, the number 12 is written in binary as 0b1100. If we bit shift by 1 to the right, we get 0b110 = 6. If we bit shift by 2, we get 0b11 = 3. And lastly, if we bitshift by 3, we get 0b1 = 1 rather than 1.5. This is because the bits that are shifted beyond the register are lost.

One easy way to think of it is bitshifting to the right by N is the same as dividing by 2^N and then truncating the result.

Justin Peel
+2  A: 

The other answers explain the idea of bitshifting, but here's specifically what happens for 100>>3

100
128 64 32 16 8 4 2 1
  0  1  1  0 0 1 0 0 = 100
100 >> 1
128 64 32 16 8 4 2 1
  0  0  1  1 0 0 1 0  = 50
100 >> 2
128 64 32 16 8 4 2 1
  0  0 0  1  1 0 0 1  = 25
100 >> 3
128 64 32 16 8 4 2 1
  0  0  0  0 1 1 0 0  = 12

You won't often need to use it, unless you need some really quick division by 2, but even then, DON'T USE IT. it makes the code much more complicated then it needs to be, and the speed difference is unnoticeable.

The main time you'd ever need to use it would be if you're working with binary data, and you specifically need to shift the bits around. The only real use I've had for it was reading & writing ID3 tags, which stores size information in 7-bit bytes, like so:

0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx.

which would need to be put together like this:

0000xxxx xxxxxxxx xxxxxxxx xxxxxxxx

to give a normal integer in memory.

Slokun