【问题标题】:Convert Bitfield to array将位域转换为数组
【发布时间】:2015-12-15 06:09:01
【问题描述】:

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

我会做这样的事情:

if(Forced & 512)
   doStuff();

我要做的是强制放入一个数组,然后变成:

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

.NET 中是否有方便的方法来执行此操作?将位域转换为数组的便捷方法是什么?

【问题讨论】:

  • 为什么?使用<< 访问位是微不足道的,例如Forced & (1 << bitNumber)...

标签: c# arrays


【解决方案1】:

你可以为此编写一个扩展方法:

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();

显然,需要添加一些关于位数 >= 0 或

【讨论】:

    【解决方案2】:

    使用位移来访问整数Forced &amp; (1 &lt;&lt; bitNumber) 的位听起来是一个不错的方法(包装访问的好函数显示在Ron Beyer's answer 中)。

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

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

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

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

    【讨论】:

    • 位数组的合法目的通常是微优化性能和/或内存使用。不确定我是否会建议 Linq 答案,因为它可能会使微优化的任何收益无效。再说一次,位数组可能在许多不需要优化的情况下使用......
    • @EricJ。我严重怀疑 OP 是否正在寻找微优化 - (int)Math.Log(512,2) 看起来不像在性能敏感代码中使用的任何东西。可能是其他一些原因 - 也许使用数组会使特定代码更具可读性? (如果性能/大小很重要,也可以使用索引器将整数包装到结构中)
    • 也许不是 OP,但我刚刚阅读了stackoverflow.com/q/21877966/141172,它提醒我人们有复制和使用他们不完全理解的代码的习惯。出于这个原因,我更喜欢 Ron 给出的答案,或者更喜欢您在问题下的评论。
    • @EricJ。 :) 它甚至变得更奇怪 - 人们复制粘贴代码,而不是给别人复制,第三人必须回到 SO 寻求解释,就像发生了 in this question
    【解决方案3】:
    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;
        }
    }
    

    【讨论】:

    • 你能解释一下你的代码吗?特别是,您如何回答“将位域转换为数组的便捷方法是什么?”这个问题?您应该知道您的答案在 queue for deletion 中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 2016-11-15
    • 2010-10-15
    • 2019-12-13
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    相关资源
    最近更新 更多