How do you write your Flagged Enums?
A while ago i explained why do you need a [Flags] attribute on the Enum here.
We'll since then i was happy with my flags until i got to the point of having 16 flags.
So why is that a problem? Well it's not really but 2^16 is how much?
If you had to open the all mighty calculator you see my point. I stop counting powers of 2 after 4096 = 2^12.
I see no reason to remember those.
That's why I wanted to write my enums a bit simpler. Like saying this is 2 to the power of 1, 2, 3, 4 etc
Using Math.Pow won't work and it's not pretty. And C# doesn't have a Power operator.
So what to do?
Bit-shifting anyone? :)
I thought this didn't work in an enum but it does, so from now on i'm writing my enums like this:
[Flags] enum bq { a = 0, // returns 0 b = 2 >> 1, // returns 1 = 2 to power of 0 c = 2 << 0, // returns 2 = 2 to power of 1 d = 2 << 1, // returns 4 = 2 to power of 2 e = 2 << 2, // returns 8 = 2 to power of 3 f = 2 << 3, // returns 16 = 2 to power of 4 g = 2 << 4 // returns 32 = 2 to power of 5 // etc, etc, etc }
Quick bit-shifting lesson:
2 << n: a left arithmetic shift by n is equivalent to multiplying by 2n
2 >> n: a right arithmetic shift by n is equivalent to dividing by 2n
Of course you have to watch for overflow with this.
Happy enuming. :)
Legacy Comments
James Curran
2007-03-06 |
re: How do you write your Flagged Enums? It's a wee bit easier if base it on 1 instead of 2: [Flags] enum bq { a = 0, // returns 0 b = 1 << 0, // returns 1 = 2 to power of 0 c = 1 << 1, // returns 2 = 2 to power of 1 d = 1 << 2, // returns 4 = 2 to power of 2 e = 1 << 3, // returns 8 = 2 to power of 3 f = 1 << 4, // returns 16 = 2 to power of 4 g = 1 << 5 // returns 32 = 2 to power of 5 // etc, etc, etc } |
Mladen
2007-03-06 |
re: How do you write your Flagged Enums? thanx for that, James |
Jesse
2007-03-10 |
re: How do you write your Flagged Enums? this is nice, except for the a=0 part. The whole point of a Flags enum is so you can or multiple values together. How would you check for the "a" value in a bitwise &? you can't. a Flags enum should not have a member with value 0 imo. :) |
Mladen
2007-03-10 |
re: How do you write your Flagged Enums? acctually a value 0 is recommended by MS to be NONE so you can also handle that option. |
jesse
2007-03-14 |
re: How do you write your Flagged Enums? I don't care much if ms recommends it - it's impossible to check for in the normal way you check for elements in a bit mask, which is with bitwise and - so i would never use it. |
mike
2008-01-11 |
re: How do you write your Flagged Enums? > Of course you have to watch for overflow with this. It should be noted that you have to manually check for this b/c shifting will not produce a compile error or runtime exception. 1 << 1 == 1 << 33 |
Daniel
2008-05-21 |
re: How do you write your Flagged Enums? I tend to use hexadecimal, there is an easy pattern of hexadecimal digits for powers of 2: enum myFlags: int { NONE = 0, Flag1 = 0x00000001, // decimal 1 Flag2 = 0x00000002, // decimal 2 Flag3 = 0x00000004, // decimal 4 Flag4 = 0x00000008, // decimal 8 Flag5 = 0x00000010, // decimal 16 Flag6 = 0x00000020, // decimal 32 Flag7 = 0x00000040, // decimal 64 Flag8 = 0x00000080, // decimal 128 Flag9 = 0x00000100, // decimal 256 Flag10 = 0x00000200, // decimal 512 ... etc } of course, you don't have to use all those leading zeros - but it is useful as a double-check for how many digits you can fit into the particular number type you've declared (in this case 32 bits = 8 hex digits). hth |