I want some Moore

Blog about stuff and things and stuff. Mostly about SQL server and .Net
posts - 218, comments - 2281, trackbacks - 33

My Links

Advertisement

News

Hi! My name is 
Mladen Prajdić  I'm from Slovenia and I'm currently working as a .Net (C#) and SQL Server developer.

I also speak at local user group meetings and conferences like SQLBits and NT Conference
Welcome to my blog.
SQL Server MVP

My Books

SQL Server MVP Deep Dives 2
The Red Gate Guide to SQL Server Team based Development Free e-book

My Blog Feed via Email
Follow MladenPrajdic on Twitter


Users Online: who's online

Article Categories

Archives

Post Categories

Cool software

Other Blogs

Other stuff

SQL stuff

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. :)

Print | posted on Monday, March 05, 2007 10:10 PM | Filed Under [ .Net ]

Feedback

Gravatar

# 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
}
3/6/2007 3:51 PM | James Curran
Gravatar

# re: How do you write your Flagged Enums?

thanx for that, James


3/6/2007 5:02 PM | Mladen
Gravatar

# 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. :)
3/10/2007 8:50 PM | Jesse
Gravatar

# 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.
3/10/2007 9:00 PM | Mladen
Gravatar

# 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.
3/14/2007 3:34 PM | jesse
Gravatar

# 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
1/11/2008 4:44 PM | mike
Gravatar

# 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
5/21/2008 11:54 AM | Daniel
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET