计算枚举上设置的标志数

Ian*_*Ian 19 c# enums

我相信必须有一个更好的方法来做到这一点.我正在尝试对Flags枚举进行计数操作.在我尝试所有可能的值并计算成功的AND操作之前.

例如

[Flags]
public enum Skills
{
    None = 0,
    Skill1 = 1,
    Skill2 = 2,
    Skill3 = 4,
    Skill4 = 8,
    Skill5 = 16,
    Skill6 = 32,
    Skill7 = 64,
    Skill8 = 128
}

public static int Count(Skills skillsToCount)
{
   Skills skill;
   for (int i = 0; i < SkillSet.AllSkills.Count; i++)
   {
      skill = SkillSet.AllSkills[i];
      if ((skillsToCount & skill) == skill && skill != Skills.None)
         count++;
   }
   return count;
}
Run Code Online (Sandbox Code Playgroud)

我确信必须有更好的方法来做到这一点,但必须患有精神障碍.谁能建议更好的解决方案?

ste*_*ell 28

下面的代码将为您提供为给定数量的任何类型设置的位数,其大小从byte到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;
}
Run Code Online (Sandbox Code Playgroud)

这段代码非常有效,因为它只针对每个位迭代一次,而不是像其他示例那样针对每个可能的位迭代一次.


Ian*_*Ian 7

在查看网站后,Assaf建议我设法找到一个稍微不同的解决方案,我为Int32工作.

这是其他任何人的代码:

    internal static UInt32 Count(this Skills skills)
    {
        UInt32 v = (UInt32)skills;
        v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
        v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
        UInt32 c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count
        return c;
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果有人感兴趣,这被称为 Hemming wight。来自维基百科的更多详细信息:https://en.wikipedia.org/wiki/Hamming_weight (2认同)

Mag*_*ron 7

如果您的目标是 .NET Core 3.0 或更高版本,则可以使用,它在orBitOperations.PopCount()中运算并返回位数。uintulong1

如果您的 CPU 支持 SSE4,它将使用POPCNTCPU 指令,否则它将使用软件回退。

public static int Count(Skills skillsToCount)
{
   return BitOperations.PopCount((ulong)skillsToCount);
}
Run Code Online (Sandbox Code Playgroud)


Neo*_*Neo 5

使用BitArray和LINQ的一种非常简洁的方法:

public static int Count(Skills skillsToCount)
{
    return new BitArray(new[] {(int)skillsToCount}).OfType<bool>().Count(x => x);
}
Run Code Online (Sandbox Code Playgroud)