Mladen Prajdić Blog

Blog about stuff and things and stuff. Mostly about SQL server and .Net

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