views:

163

answers:

5

I ran into this statement in a piece of code:

Int32 medianIndex = colorList.Count >> 1;

colorList is a list of class System.Drawing.Color.

Now the statement is supposed to retrieve the median index of the list .. like the half point of it .. but I can't understand how that >> symbol works and how the "1" is supposed to give the median index .. I would appreciate some help :S

+7  A: 

The >> operator performs a bit shift.

The expression >> 1 is almost* the same as / 2 so the programmer was calculating the index colorList.Count / 2 which is** the median. To understand why this is the case you need to look at the binary representation of the numbers involved. For example if you have 25 elements in your list:

n     : 0 0 0 1 1 0 0 1 = 25
         \ \ \ \ \ \ \
n >> 1: 0 0 0 0 1 1 0 0 = 12

In general using a bitwise operator when really you want to perform a division is a bad practice. It is probably a premature optimization made because the programmer thought it would be faster to perform a bitwise operation instead of a division. It would be much clearer to write a division and I wouldn't be surprised if the performance of the two approaches is comparable.

*The expression x >> 1 gives the same result as x /= 2 for all positive integers and all negative even integers. However it gives a different result for negative odd integers. -101 >> 1 == -51 whereas -101 / 2 == -50.

**Actually the median is only defined this way if the list has an odd number of elements. For an even number of elements this method will strictly speaking not give the median.

Mark Byers
thanks a lot for the explanation ..i'm familiar with the shifting method and it's meaning but i didn't get that it's the way used here .. i have another question though .. is this way of dividing on 2 has less time complexity than the normal "/" division?
Majd
@Majd: That depends on the platform where you run the code. Remember that C# is compiled into CIL, which in turn is translated (“jitted”) into native machine code that differs from platform to platform. It may well be possible that some jitters automatically translate `x/2` into a shift-right instruction.
Timwi
A: 

It's not very readable code, basically it just divides the number by 2.

>> is the shift-right operator, shifting all bits one position to the right.

0110 (6) becomes 0011 (3)

dbemerlin
bits, not bytes.
Timwi
@Timwi: Thanks, of course you are right, corrected it.
dbemerlin
+1  A: 

>> is the bitwise right-shift operator, and shifting colorList.Count to the right by 1 is more or less equivalent to colorList.Count / 2.

A right shift of a >> b can be defined as a / 2 ^ b.

As for why you would use a right-shift rather than divide by 2, I have no idea.

rfw
+2  A: 

It's a bitwise opperator a definition i just grabbed from http://en.wikibooks.org/wiki/C_Sharp_Programming/Operators:

The binary operator >> evaluates its operands and returns the resulting first argument right-shifted by the number of bits specified by the second argument. It discards low-order bits that are shifted beyond the size of its first argument and sets new high-order bits to the sign bit of the first argument, or to zero if the first argument is unsigned.

Its basically dividing by 2...

robinsonc494
+1 for linking to documentation. I find if funny the OP even bothered to post here instead of just heading over to langauge definitions. Asking a question like that is something that makes me talk to my employees about their attitude (not: I dont understand what bigshift is" but "hey, i am too lazy to look up language specs for code I review").
TomTom
+1  A: 

C programmers (of which I've been one for over 20 years) routinely have used bitwise shifts for multiplying or dividing by powers of 2. The reason was that in older architectures (think 2 MHz processor, 32K of memory, and no disk) it was significantly faster to shift and generally compiled to a single machine instruction. Even though I write primarily C# now, I still, as a mater of habit, sometimes use this trick. Another common C convention that most C# programmers have never seen is having an assignment embedded within a conditional. For example:

if ( (a = getmeanumber()) == 0 )
   /* do something */ ;

Anyway, as to the original question and the reasons for its use, they largely no longer exist except with the limited realm of embedded programming where every byte and clock cycle could matter.

BillP3rd