39

I was looking at the code I have currently in my project and found something like this:

public enum MyEnum
{
    open     = 1 << 00,
    close    = 1 << 01,
    Maybe    = 1 << 02,
    ........
}

The << operand is the shift operand, which shifts the first operand left by the number bits specified in the second operand.

But why would someone use this in an enum declaration?

Smi
  • 13,850
  • 9
  • 56
  • 64
JSBach
  • 4,679
  • 8
  • 51
  • 98
  • @GrantWinney (not my close votes) but I see how it is "opinion-based" because the question is essentially "why someone uses `1 << 2` when `0x04` is more readable *for me*". – Alexei Levenkov Jul 26 '13 at 18:30
  • 7
    I never said 0x04 is more readable nor have I compared both. The intent of the question is to understand the side effects of this statement (= being able to combine flags) – JSBach Jul 26 '13 at 18:42
  • 2
    Oscar, there is nothing wrong with your post (and I think it is useful for someone learning to code in any of C/C++/C#/Java/JavaScript). But different people read the same text differently - I just put my way of reading it which I believe explains votes to close. – Alexei Levenkov Jul 26 '13 at 18:56
  • 2
    I would be careful prefixing a leading zero to the bit shifts - doesn't the literal get interpreted as octal if there is no `8` or `9` then? That could make for a good hour or two of debugging. – Thomas Jul 27 '13 at 00:11
  • If you know C: read - [What is the meaning of this declaration?](http://stackoverflow.com/questions/15708493/what-is-the-meaning-of-this-declaration/15708566#15708566) – Grijesh Chauhan Jul 27 '13 at 06:31
  • @Thomas No, even with leading zeroes they are still interpreted as decimal, not octal (this is C#). – Jeppe Stig Nielsen Jul 28 '13 at 08:35
  • Was this `enum` type decorated with [`[Flags]`](http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx)? See the documentation on that page. – Jeppe Stig Nielsen Jul 28 '13 at 08:39

7 Answers7

40

This allows you to do something like this:

var myEnumValue = MyEnum.open | MyEnum.close;

without needing to count bit values of multiples of 2.

(like this):

public enum MyEnum
{
    open     = 1,
    close    = 2,
    Maybe    = 4,
    ........
}
Mark Avenius
  • 13,679
  • 6
  • 42
  • 50
  • 1
    **Note**: [`<<` declaration will give you a maximum of up to `64` different states (on most platforms). If you need more possible states, this solution will not work](http://stackoverflow.com/questions/8956364/app-states-with-bool-flags?answertab=votes#8956606) – Grijesh Chauhan Jul 27 '13 at 06:33
  • 2
    What alternative solution will give more than 64 orthogonal states? – Useless Jul 27 '13 at 10:34
  • 2
    @GrijeshChauhan Most platforms? This is C# so the size of integer types does not depend on platform. The type of the left operand to the `<<` operator determines which overload to use. For example, with `s` an integer, `1 << s` gives a 32-bit `int`, `1u << s` gives 32-bit unsigned `uint`, `1L << s` gives 64-bit `long`, `1ul << s` is `ulong`, and `(BigInteger)1 << s` or `BigInteger.One << s` gives an arbitrarily-sized integer (requires reference to `System.Numerics.dll` assembly). – Jeppe Stig Nielsen Jul 28 '13 at 08:55
  • @JeppeStigNielsen Got it!...I am not from [tag:C#] background I felt I should share the answer as I was aware of that. ...btw I don't like [tag:C#] here if in [tag:C#], `sizeof(enum)` > `sizeof(one byte)` because no one like to use `2^sizeof(int)` symbolic constants in his code. – Grijesh Chauhan Jul 28 '13 at 09:02
  • 2
    @GrijeshChauhan In C#, you can make an 8-bit enum type like this: `public enum Color : byte { Red, Yellow, Green, Blue, }` – Jeppe Stig Nielsen Jul 28 '13 at 09:06
  • @JeppeStigNielsen Is it!! its wonderful feature. Thanks Jeepe! – Grijesh Chauhan Jul 28 '13 at 09:09
22

This is usually used with bitfields, since it's clear what the pattern is, removes the need to manually calculate the correct values and hence reduces the chance of errors

[Flags]
public enum SomeBitField
{
    open = 1 << 0    //1
    closed = 1 << 1  //2
    maybe = 1 << 2   //4
    other = 1 << 3   //8
    ...
}
Lee
  • 142,018
  • 20
  • 234
  • 287
  • I think you mean bitwise operations, not bitfields. Bitfields, at least in C world, are sub-byte struct members. – noamtm Aug 05 '13 at 05:52
10

To avoid typing out the values for a Flags enum by hand.

public enum MyEnum
{
    open     = 0x01,
    close    = 0x02,
    Maybe    = 0x04,
    ........
}
Richard Deeming
  • 29,830
  • 10
  • 79
  • 151
6

It's just meant to be a cleaner / more intuitive way of writing the bits. 1, 2, 3 is a more human-readable sequence than 0x1, 0x2, 0x4, etc.

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
6

This is to make an enum that you can combine.

What it effectively means is this:

public enum MyEnum
{
    open = 1;
    close = 2;
    Maybe = 4;
    //...
}

This is just a more bulletproof method of creating a [Flags] enum.

It'sNotALie.
  • 22,289
  • 12
  • 68
  • 103
6

Lots of answers here describing what this mechanic allows you to do, but not why you would want to use it. Here's why.

Short version:

This notation helps when interacting with other components and communicating with other engineers because it tells you explicitly what bit in a word is being set or clear instead of obscuring that information inside a numeric value.

So I could call you up on the phone and say "Hey, what bit is for opening the file?" And you'd say, "Bit 0". And I'd write in my code open = 1 << 0. Because the number to the right of << tells you the bit number.

.

Long version:

Traditionally bits in a word are numbered from right to left, starting at zero. So the least-significant bit is bit number 0 and you count up as you go toward the most-significant bit. There are several benefits to labeling bits this way.

One benefit is that you can talk about the same bit regardless of word size. E.g., I could say that in both the 32-bit word 0x384A and 8-bit word 0x63, bits 6 and 1 are set. If you numbered your bits in the other direction, you couldn't do that.

Another benefit is that a bit's value is simply 2 raised to the power of the bit position. E.g., binary 0101 has bits 2 and 0 set. Bit 2 contributes the value 4 (2^2) to the number, and bit 0 contributes the value 1 (2^0). So the number's value is of course 4 + 1 = 5.

That long-winded background explanation brings us to the point: The << notation tells you the bit number just by looking at it.

The number 1 by itself in the statement 1 << n is simply a single bit set in bit position 0. When you shift that number left, you're then moving that set bit to a different position in the number. Conveniently, the amount you shift tells you the bit number that will be set.

1 << 5:   This means bit 5.   The value is 0x20.
1 << 12:  This means bit 12.  The value is 0x40000.
1 << 17:  This means bit 17.  The value is 0x1000000.
1 << 54:  This means bit 54.  The value is 0x40000000000000.
          (You can probably see that this notation might be helpful if
          you're defining bits in a 64-bit number)

This notation really comes in handy when you're interacting with another component, like mapping bits in a word to a hardware register. Like you might have a device that turns on when you write to bit 7. So the hardware engineer would write a data sheet that says bit 7 enables the device. And you'd write in your code ENABLE = 1 << 7. Easy as that.

Oh shoot. The engineer just sent an errata to the datasheet saying that it was supposed to be bit 15, not bit 7. That's OK, just change the code to ENABLE = 1 << 15.

What if ENABLE were actually when both bits 7 and 1 were set at the same time?

ENABLE = (1 << 7) | (1 << 1).

It might look weird and obtuse at first, but you'll get used to it. And you'll appreciate it if you ever explicitly need to know the bit number of something.

indiv
  • 17,306
  • 6
  • 61
  • 82
0

It is equal to powers of two.

public enum SomeEnum
{
    Enum1 = 1 << 0,    //1
    Enum2 = 1 << 1,    //2
    Enum3 = 1 << 2,    //4
    Enum4 = 1 << 3     //8
}

And with such enum you will have function which looks like this:

void foo(unsigned ind flags)
{
    for (int = 0; i < MAX_NUMS; i++)
        if (1 << i & flags)
        {
            //do some stuff...
            //parameter to that stuff probably is i either enum value
        }
}

And call to that function would be foo(Enum2 | Enum3); and it will do something with all given enum values.

ST3
  • 8,826
  • 3
  • 68
  • 92