43

Basically the questions in the title. I'm looking at the MVC 2 source code:

[Flags]
public enum HttpVerbs {
    Get = 1 << 0,
    Post = 1 << 1,
    Put = 1 << 2,
    Delete = 1 << 3,
    Head = 1 << 4
}

and I'm just curious as to what the double left angle brackers << does.

lancscoder
  • 8,658
  • 8
  • 48
  • 68

15 Answers15

130

When you write

1 << n

You shift the bit combination 000000001 for n times left and thus put n into the exponent of 2:

2^n

So

1 << 10

Really is

1024

For a list of say 5 items your for will cycle 32 times.

pid
  • 11,472
  • 6
  • 34
  • 63
  • So this is the same as `for (int i = 0; i < Math.Pow(2, list.Count)); i++)`? – Robert Fricke Jan 29 '14 at 10:48
  • @RobertFricke I would be careful by using `<` with `int` and `double` – Ilya Ivanov Jan 29 '14 at 10:49
  • 8
    @Robert Fricke: Yes. Bit shifting is limited to a base of 2 (disadvantage) but extremely faster (advantage) than Math.Pow() which is more flexible and can even have floating point bases and exponents. It becomes a single machine code instruction. – pid Jan 29 '14 at 10:50
  • @Ilya Ivanov `for (int i = 0; i < Convert.ToInt32(Math.Pow(2, list.Count))); i++)`? – Robert Fricke Jan 29 '14 at 10:50
  • 5
    @RobertFricke you see, how suddenly `1 << list.Count` just shines, as to be compared to `Convert.ToInt32(Math.Pow(2, list.Count)))` ) – Ilya Ivanov Jan 29 '14 at 10:51
  • @Ilya: true, I'd prefer unsigned types but even then bit-wise operations are relatively uncommon in high-level c# code. – pid Jan 29 '14 at 10:51
  • 29
    @IlyaIvanov Haha, yes. And also how your employer never can let you go anymore: your code is lightning fast, and the other developers can't understand it. – Robert Fricke Jan 29 '14 at 10:55
  • 7
    I find it hard to believe performance is such a premium that it would not make more sense to `Math.Pow` _once_ to find the loop count. Then you don't have to worry about tripping up developers with shifting nonsense. – Gusdor Jan 29 '14 at 10:57
  • 2
    @Gusdor: for enterprise applications I'd discourage code difficult to read. It's much better to pay performance for readability. So I agree with you here. – pid Jan 29 '14 at 10:59
  • 3
    Assuming the list is not changed inside the loop it would be more efficient to calculate the number of iterations only once before the loop. – Andris Jan 29 '14 at 12:34
  • 4
    The left shift and other bitwise operators are commonly used in embedded development where even a couple of cycles are important to performance. Bitwise operators are supported directly by the processor and used in other programming languages. You don't have to add functions make them work saving space in low memory situations. Yeah if you are working with a .NET based application on a modern computer you can just include the Math library and not worry about bitmath but don't expect to do the same thing in something like the AVR-GCC toolchain and not have it affect performance. – Sisco Jan 29 '14 at 14:00
  • 3
    As @Andris said, this code is most probably inefficient anyway. Also, why should a left shift be quicker than Math.Pow(2, n)? Wouldn't anyone here expect Math.Pow to perform a left shift in this case? – Shautieh Jan 29 '14 at 14:45
  • 1
    @Shautieh: Even if Math.Pow does do a left shift it has to analyze the parameters in order to determine if it even can do that, so there's a necessary extra operation either way. – Patrick Jan 29 '14 at 15:05
  • 3
    @Shautieh, Even if `Math.Pow` uses left-shift in the case of a base of 2, you've got at _minimum_: (1) a method call, (2) a conditional to check if the base is equal to 2, (3) a conditional to ensure that the power can be converted to an integer without loss of precision, and (4) a left-shift. Compared to an explicit left-shift which is a single operation, `Pow` would be slower. – Brian S Jan 29 '14 at 15:18
  • 3
    If **list.Count** isn't going to change during the loop, it _might_ be more efficient to move the operation outside the loop as a variable assign (depends on how well the optimizer does). In any case, a comment to gently remind a reader what this unusual operation (rarely used idiom) does ("upper bound is 2^list.Count") would be appropriate, even for experienced programmers. – Phil Perry Jan 29 '14 at 16:00
  • 5
    @Ingo: Not everyone here has the same experience as you. I guarantee there was once a day when you didn't know the << operator. Have some basic respect for those who are still learning (without them, there'd be no SO). – Plutor Jan 29 '14 at 16:40
  • 5
    The first time you encounter a left/right shift it seems confusing and foreign. Pretty soon though, you'll recognize the brilliance and start using them everywhere. That's why it's always a good idea to familiarize yourself with bitwise operators if you're learning any C derivative. It'll come in handy. – Mordred Jan 29 '14 at 16:46
  • 4
    The fact that they are using list.Count makes me think they're over optimizing the wrong part of the code – BlackTigerX Jan 29 '14 at 16:50
  • 2
    @BrianS Not if the optimization is done at compile-time. Unless the performance is strictly necessary and you know your compiler won't perform the optimization, this may be a case of premature optimization. – rob Jan 29 '14 at 16:56
  • 1
    Are there any case where the Pow() and << will give different answers due to rounding ? – BlueTrin Jan 29 '14 at 17:59
  • 6
    @Plutor Not knowing it is ok (that's what Language specifications are for). Finding it "hard to understand", "hard to read", "other developers can't understand it" or something, is a sign of unwillingness to learn anything beyond +,-,*,/. Either that or complete unfamiliarity with what integers are and how they're represented. The workaround `Math.pow(n,2)` is simply grotesque. For example, in Java it will entail conversions to and from double – Ingo Jan 29 '14 at 18:34
  • 1
    @rob, While true, that's the compiler being intelligent, not `Pow` being efficient. – Brian S Jan 29 '14 at 18:49
  • 26
    I'm not sure why everyone sees this as an *optimization*. To me, it's the natural idiom for expressing power-of-two, and I would never consider writing it another way. Using a library function for performing power-of-two calculations makes it harder to read (horrible prefix notation, rather than `value operator value` which is much more readable). Seriously, do you *really* think that `Convert.ToInt32(Math.Pow(2,value))` is more readable than `1< – Jules Jan 29 '14 at 19:02
  • 2
    And don't you see it as your responsibility to understand the meaning of all of your language's built-in operations? – Jules Jan 29 '14 at 19:03
  • 2
    @BrianS My point is that the theoretical efficiency of `<<` over `pow` is irrelevant unless you know your compiler isn't going to optimize `pow`. If you're using `<<` for a reproducible real-world performance scenario, you should document it so a future maintainer who thinks `pow` is clearer does not replace it on a whim. – rob Jan 29 '14 at 19:14
  • @rob: The compiler *can't* optimize `pow(2, c)` to `1 << c` unless it can prove that `c < CHAR_BIT * sizeof c`. – Ben Voigt Jan 29 '14 at 20:42
  • 1
    @JackAidley Me, too. I'm in that generation. I often wish I had the experience with this kind of thing. The truth is that it's just not necessary anymore except in very advanced or arcane cases (hardcore cryptanalysis and penetration testing, for example). – asteri Jan 29 '14 at 21:06
  • 2
    I think it is fair to mention that the left/right shift operators does not work on floating-point precision variables like float or double so for those variables one must cast it to an int/long, perform the shift, then cast back. Data will most likely be lost in the process if not handled correctly. – John Odom Jan 29 '14 at 21:52
  • 2
    I wonder why this question attracts so much attention. It's really the most trivial thing I've answered so far... – pid Jan 29 '14 at 22:18
82

It is called left-shift operator. Take a look at the documentation

The left-shift operator causes the bit pattern in the first operand to be shifted to the left by the number of bits specified by the second operand. Bits vacated by the shift operation are zero-filled. This is a logical shift instead of a shift-and-rotate operation.

Simple example that demonstrates the left-shift operator:

for (int i = 0; i < 10; i++)
{
    var shiftedValue = 1 << i;
    Console.WriteLine(" 1 << {0} = {1} \t Binary: {2}",i,shiftedValue,Convert.ToString(shiftedValue,2).PadLeft(10,'0'));
}

//Output:

// 1 << 0 = 1      Binary: 0000000001
// 1 << 1 = 2      Binary: 0000000010
// 1 << 2 = 4      Binary: 0000000100
// 1 << 3 = 8      Binary: 0000001000
// 1 << 4 = 16     Binary: 0000010000
// 1 << 5 = 32     Binary: 0000100000
// 1 << 6 = 64     Binary: 0001000000
// 1 << 7 = 128    Binary: 0010000000
// 1 << 8 = 256    Binary: 0100000000
// 1 << 9 = 512    Binary: 1000000000

Moving one bit to left is equivelant to multiple by two.In fact,moving bits are faster than standart multiplication.Let's take a look at an example that demonstrates this fact:

Let's say we have two methods:

static void ShiftBits(long number,int count)
{
    long value = number;
    for (int i = 0; i < count; i+=128)
    {
          for (int j = 1; j < 65; j++)
          {
              value = value << j;
          }
          for (int j = 1; j < 65; j++)
          {
               value = value >> j;
          }
    }
}

static void MultipleAndDivide(long number, int count)
{
      long value = number;
      for (int i = 0; i < count; i += 128)
      {
            for (int j = 1; j < 65; j++)
            {
                value = value * (2 * j);
            }
            for (int j = 1; j < 65; j++)
            {
                value = value / (2 * j);
            }
      }
}

And we want to test them like this:

ShiftBits(1, 10000000);
ShiftBits(1, 100000000);
ShiftBits(1, 1000000000);
...
MultipleAndDivide(1, 10000000);
MultipleAndDivide(1, 100000000);
MultipleAndDivide(1, 1000000000);
...

Here is the results:

Bit manipulation 10.000.000 times: 58 milliseconds
Bit manipulation 100.000.000 times: 375 milliseconds
Bit manipulation 1.000.000.000 times: 4073 milliseconds

Multiplication and Division 10.000.000 times: 81 milliseconds
Multiplication and Division 100.000.000 times: 824 milliseconds
Multiplication and Division 1.000.000.000 times: 8224 milliseconds
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • We tend to prefer bitwise rotations over bitwise shifts in cryptography. Shifts are used in some places, but they're not nearly as common as rotations. – Reid Jan 29 '14 at 18:24
  • This is quite generalized. I'm uncomfortable with it to tell you the truth. I'm mostly uncomfortable with the fact that you failed to mention that it performs (value)*2^n very quickly. Also, the examples that you mention are (while true) missing the point I feel. – violet_white Jan 29 '14 at 18:24
  • 3
    @jaked122 is it enough now ? :) – Selman Genç Jan 30 '14 at 04:53
63

That would be the bitwise left shift operator.

For each shift left, the value is effectively multiplied by 2. So, for example, writing value << 3 will multiply the value by 8.

What it really does internally is move all of the actual bits of the value left one place. So if you have the value 12 (decimal), in binary that is 00001100; shifting it left one place will turn that into 00011000, or 24.

Aaronaught
  • 120,909
  • 25
  • 266
  • 342
57

It is Bitwise shift left it works by shifting digits of binary equivalent of number by the given (right hand side) numbers.

so:

temp = 14 << 2

binary equivalent of 14 is 00001110 shifting it 2 times means pushing zero from right hand side and shifting each digit to left side which make it 00111000 equals to 56.

visual

In your example:

i < (1 << list.Count)
  • 0000000001 = 1 if list.Count = 0 result is 0000000001 = 1
  • 0000000001 = 1 if list.Count = 1 result is 0000000010 = 2
  • 0000000001 = 1 if list.Count = 2 result is 0000000100 = 4
  • 0000000001 = 1 if list.Count = 3 result is 0000001000 = 8

and so on. In general it is equal 2 ^ list.Count (2 raised to the power of list.Count)

Zaheer Ahmed
  • 28,160
  • 11
  • 74
  • 110
37

That's the left bitshift operator. It shifts the bit pattern of the left operand to the left by the number of binary digits specified in the right operand.

Get = 1 << 0, // 1
Post = 1 << 1, // 2
Put = 1 << 2,  // 4
Delete = 1 << 3, // 8
Head = 1 << 4  // 16

This is semantically equivalent to lOperand * Math.Pow(2, rOperand)

Adam Robinson
  • 182,639
  • 35
  • 285
  • 343
  • +1 for actually showing what the left bitshift is doing in this case. – auujay Mar 22 '10 at 15:43
  • 8
    Or More Specifically: 00001, 00010, 00100, 01000, 10000 – zmbush Mar 22 '10 at 15:48
  • 1
    "by the number of binary digits specified in the right operand" - actually, that isn't *quite* right; for 32-bit, for example, it only considers the first 5 bits, so `<< 33` is **identical** to `<< 1`. Likewise in 64-bit math, `<< 65` is **identical** to `<< 1`. And right-shift is more complex again, as you need to consider the sign to know what to backfill with. – Marc Gravell Mar 23 '10 at 16:50
23

The purpose of the loop is most likely to generate or operate on all subsets of the set of items in the list. And the loop body most likely also has a good bit (har har) of bitwise operations, namely both another left-shift and bitwise-and. (So rewriting it to use Pow would be mighty stupid, I can hardly believe there were so many people that actually suggested that.)

user2451227
  • 463
  • 5
  • 9
  • 4
    +1 for the suggestion that this involves subsets of the list elements, which seems the only reasonable motive to do such a thing. One might want to add that this is a very bad technique if there is any chance at all that the list will be fairly long, namely longer than the number of bits in an `int` (one might guess that with all bits shifted away the loop would be exectuted 0 times, but in reality I think the behaviour is undefined; in fact I recall that shifting bits over exactly the word length often does nothing at all). – Marc van Leeuwen Jan 29 '14 at 15:45
15

Thats bit shifting. Its basically just moving the bits to the left by adding 0's to the right side.

public enum HttpVerbs {
    Get = 1 << 0,    // 00000001 -> 00000001 = 1
    Post = 1 << 1,   // 00000001 -> 00000010 = 2
    Put = 1 << 2,    // 00000001 -> 00000100 = 4
    Delete = 1 << 3, // 00000001 -> 00001000 = 8
    Head = 1 << 4    // 00000001 -> 00010000 = 16
}

More info at http://www.blackwasp.co.uk/CSharpShiftOperators.aspx

Fabian
  • 13,603
  • 6
  • 31
  • 53
12

In addition to Selman22's answer, some examples:

I'll list some values for list.Count and what the loop would be:

list.Count == 0: for (int i = 0; i < 1; i++)
list.Count == 1: for (int i = 0; i < 2; i++)
list.Count == 2: for (int i = 0; i < 4; i++)
list.Count == 3: for (int i = 0; i < 8; i++)

And so forth.

chue x
  • 18,573
  • 7
  • 56
  • 70
Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
9

"Bit shift left." 1 << 0 means "take the integer value 1 and shift its bits left by zero bits." I.e., 00000001 stays unchanged. 1 << 1 means "take the integer value 1 and shift its bits left one place." 00000001 becomes 00000010.

Dathan
  • 7,266
  • 3
  • 27
  • 46
8

Its (<<) a bitwise left shift operator, it moves the bit values of a binary object. The left operand specifies the value to be shifted and the right operand specifies the number of positions that the bits in the value are to be shifted.

In your case if the value of list.count is 4 then loop will run till i < (1<< 4) which is 16 (00010000)

00000001 << 4 = 00010000(16)

gaurav
  • 103
  • 1
  • 2
  • 9
7

The expression (1 << N) uses a Bit Shift in c#.

In this case it's being used to perform a fast integer evalution of 2^N, where n is 0 to 30.

A good tool for young whippersnappers developers that don't understand how bit shifts work is Windows Calc in programmer mode, which visualises the effect of shifts on signed numbers of various sizes. The Lsh and Rsh functions equate to << and >> respectively.

Evaluating using Math.Pow inside the loop condition is (on my system) about 7 times slower than the question code for N = 10, whether this matters depends on the context.

Caching the "loop count" in a separate variable would speed it up slightly as the expression involving the list length would not need to be re-evaluated on every iteration.

Community
  • 1
  • 1
Peter Wishart
  • 11,600
  • 1
  • 26
  • 45
  • `1 << list.Count` looks like it's probably loop invariant anyway, in which case a decent compiler would move it out of the loop. Given that, to some people caching it might seem like premature optimization. For me it would depend how "serious" the code is. – hippietrail Jan 29 '14 at 18:32
  • Depending on where `list` comes from, it's probably very difficult for the compiler to prove that it's loop invariant: for instance, does the compiler know it can't be modified in another thread? Or that it isn't some bizarre subclass of `List` that removes elements when they're accessed, or something similar to that? – Jules Jan 29 '14 at 19:27
  • What's that -31 to -2 bit? It seems especially odd because it's a 30-number range, while 0 to 30 is a 31-number range. (And shouldn't the range actually be 32 numbers, anyway?) – Brilliand Jan 29 '14 at 20:23
  • @Brilliand sorry, I was talking nonsense, `int << X` is the same as `int << (X-32)` but a) its irrelevant and b) the negative shifts don't compute `2^(32-X)`! – Peter Wishart Jan 29 '14 at 21:41
7

It is implied in a number of answers but never stated directly...

For every position that you shift a binary number left, you double the original value of the number.

For example,

Decimal 5 binary shifted left by one is decimal 10, or decimal 5 doubled.

Decimal 5 binary shifted left by 3 is decimal 40, or decimal 5 doubled 3 times.

GaTechThomas
  • 5,421
  • 5
  • 43
  • 69
6

Previous answers have explained what it does, but nobody seems to have taken a guess as to why. It seems quite likely to me that the reason for this code is that the loop is iterating over each possible combination of members of a list -- this is the only reason I can see why you would want to iterate up to 2^{list.Count}. The variable i would therefore be badly named: instead of an index (which is what I usually interpret 'i' as meaning), its bits represent a combination of items from the list, so (for example) the first item may be selected if bit zero of i is set ((i & (1 << 0)) != 0), the second item if bit one is set ((i & (1 << 1)) != 0) and so on. 1 << list.Count is therefore the first integer that does not correspond to a valid combination of items from the list, as it would indicate selection of the non-existant list[list.Count].

Jules
  • 14,841
  • 9
  • 83
  • 130
  • 2
    That isn't the question, though, and so this isn't really an answer. – David Conrad Jan 29 '14 at 19:38
  • 3
    I think it is an answer. Because it puts a different light on it: it isn't *just* 2^list.Count: for a particularly convenient way of enumerating selections from a list, it's calculating (I suspect) the first number that doesn't correspond to a valid selection. That this happens to be 2^list.Count, but the intent is (I'm reasonably sure) to enumerate all of those combinations, so the fact that this is the number of combinations possible is incidental to the real meaning of the loop's exit condition, which is "stop counting when we've run out of combinations of list items". – Jules Jan 29 '14 at 19:58
  • 1
    The question is, "what `(1 << list.Count)` means". Yours is an answer ... to a different question than the one the OP asked. – David Conrad Jan 29 '14 at 20:33
5

I know this answer is pretty much solved, but I thought the visualization might help someone.

[Fact] public void Bit_shift_left()
{
    Assert.Equal(Convert.ToInt32("0001", 2), 1 << 0); // 1
    Assert.Equal(Convert.ToInt32("0010", 2), 1 << 1); // 2
    Assert.Equal(Convert.ToInt32("0100", 2), 1 << 2); // 4
    Assert.Equal(Convert.ToInt32("1000", 2), 1 << 3); // 8
}
Mark
  • 9,966
  • 7
  • 37
  • 39
0

<< is the left bit shift operator. If you have the number 3, which is 00000011 in binary, you can write 3 << 2, which is 00001100, or 12 in decimal.