Search code examples
c#enumsflags

Efficient way to find the flags enum length?


Consider this:

[Flags]
enum Colors
{
    Red=1,
    Green=2,
    Blue=4
}

Colors myColor=Colors.Red|Colors.Blue;

Currently, I'm doing it as follows:

int length=myColors.ToString().Split(new char[]{','}).Length;

But I hope there is a more efficient way of finding the length, maybe based on bitset operations.

Please, if possible, provide explanation why and how your solution works.

Also, if this a duplicate, please point to it and I'll delete this question. The only similar questions on SO I've been able to find were concerned about finding the length of all possible combinations of Colors enum, but not of the myColors variable.

UPDATE: I carefully benchmarked every solution (1 000 000 iterations each) and here is the results:

  1. Stevo3000 - 8ms
  2. MattEvans - 10ms
  3. Silky - 34ms
  4. Luke - 1757ms
  5. Guffa - 4226ms
  6. Tomas Levesque - 32810ms

The Stevo3000 is a clear winner (with Matt Evans holding silver medal).

Thank you very much for your help.

UPDATE 2: This solution runs even faster: 41 ms for 100 000 000 iterations (roughly 40 times faster (32bit OS) than Stevo3000)

UInt32 v = (UInt32)co;
v = v - ((v >> 1) & 0x55555555); 
v = (v & 0x33333333) + ((v >> 2) & 0x33333333); 
UInt32 count = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; 

Solution

  • The following code will give you the number of bits that are set for a given number of any type varying in size from byte up to long.

    public static int GetSetBitCount(long lValue)
    {
      int iCount = 0;
    
      //Loop the value while there are still bits
      while (lValue != 0)
      {
        //Remove the end bit
        lValue = lValue & (lValue - 1);
    
        //Increment the count
        iCount++;
      }
    
      //Return the count
      return iCount;
    }
    

    This code is very efficient as it only iterates once for each bit rather than once for every possible bit as in the other examples.