将Bitfield转换为数组

时间:2015-12-14 20:07:35

标签: c# arrays

我有一个名为Forced的uint包含32位。

我做的事情如下:

if(Forced & 512)
   doStuff();

我要做的是强制进入一个阵列,然后变成:

if(ForcedArray[(int)Math.Log(512,2)])
   doStuff();

.NET中有一种方便的方法吗?将位域转换为数组的便捷方法是什么?

3 个答案:

答案 0 :(得分:3)

使用位移来访问整数Forced & (1 << bitNumber)的位听起来像是一种很好的方法(包含访问权限的好函数显示在Ron Beyer's answer)。

代码的大多数读者都会被紧凑的单字字段转换成像数组这样的复杂数据结构感到困惑。请考虑避免这种情况,除非有其他原因(外部API约束,如JSON序列化)或显着的可读性增益。

作为中间方法,您可以创建保存整数值的小包装器结构,并另外公开对每个位的索引访问(最好是不可变的)。

如果你真的想要和数组 - 基本for循环或LINQ可用于将每个位转换为布尔值。即如果它只是一个整数(可能需要先根据你需要的位调整顺序,这个位先放入最低位):

var array = Enumerable.Range(0, 32)
  .Select(bitNumber => (Forced & (1 << bitNumber)) !=0)
  .ToArray();

答案 1 :(得分:3)

您可以为此编写扩展方法:

public static class UIntExtensions
{
    public static bool IsBitSet(this uint i, int bitNumber)
    {
        return i & (1 << bitNumber) != 0;
    }
}

或者,如果您想以C#6方式执行此操作:

public static class UIntExtensions
{
    public static bool IsBitSet(this uint i, int bitNumber) => (i & (1 << bitNumber)) != 0;
}

从代码中可以很容易地使用它:

if(Forced.IsBitSet((int)Math.Log(512,2)))
   doStuff();

显然,需要添加一些比特数&gt; = 0或&lt; = 31的检查,但是你明白了。

答案 2 :(得分:0)

public static class UIntExtensions
{
    public static byte[] GetBitArray(this uint v)
    {
        var r = byte[32];
        for (var i = 0; i < 32; ++i)
        {
            r[i] = v & 1;
            v = v >> 1
        }
        return r;
    }
}