【问题标题】:Convert BitArray to a small byte array将 BitArray 转换为小字节数组
【发布时间】:2013-11-27 16:11:50
【问题描述】:

我已阅读有关 BitArray 转换的其他帖子,并自己尝试了几篇,但似乎都没有达到我想要的结果。

我的情况就是这样,我有一些控制 LED 灯条的 c# 代码。要向条带发出单个命令,我最多需要 28 位

1 位用于在 2 个 LED 灯条之间进行选择

6 个位置(最多 48 个可寻址 LED)

7 代表颜色 x3(0-127 代表颜色)

假设我为该结构创建了一个 BitArray,并且作为示例,我们半随机地填充它。

        BitArray ba = new BitArray(28);

        for(int i = 0 ;i < 28; i++)
        {
            if (i % 3 == 0)
                ba.Set(i, true);
            else
                ba.Set(i, false);
        }

现在我想将这 28 位粘贴到 4 个字节中(最后 4 位可以是停止信号),最后把它变成一个字符串,这样我就可以通过 USB 将字符串发送到 LED 灯条。

我尝试过的所有方法都将 1 和 0 转换为文字字符,这不是目标。

有没有一种直接的方法可以在 C# 中进行这种位压缩?

【问题讨论】:

    标签: c# bit-manipulation


    【解决方案1】:

    你可以使用BitArray.CopyTo:

    byte[] bytes = new byte[4];
    ba.CopyTo(bytes, 0);
    

    或者:

    int[] ints = new int[1];
    ba.CopyTo(ints, 0);
    

    不清楚您希望 string 表示是什么 - 您正在处理自然二进制数据而不是文本数据...

    【讨论】:

    • 谢谢乔恩。我实际上并不关心字符串表示。我使用的当前系统使用字符串编码进行通信,但我最终发送了 17 个字节来传达相同的信息。我将它转换为字符串只是因为 LibUsbDotNet 的发送方法请求它。我将使用您本周末提供的解决方案,看看我是否可以优化传输。
    【解决方案2】:

    我不会为此使用BitArray。相反,我会使用一个结构,然后在需要时将其打包到一个 int 中:

    struct Led
    {
        public readonly bool Strip;
        public readonly byte Position;
        public readonly byte Red;
        public readonly byte Green;
        public readonly byte Blue;
    
        public Led(bool strip, byte pos, byte r, byte g, byte b)
        {
            // set private fields
        }
    
        public int ToInt()
        {
            const int StripBit = 0x01000000;
            const int PositionMask = 0x3F; // 6 bits
            // bits 21 through 26
            const int PositionShift = 20;
            const int ColorMask = 0x7F;
            const int RedShift = 14;
            const int GreenShift = 7;
    
            int val = Strip ? 0 : StripBit;
            val = val | ((Position & PositionMask) << PositionShift);
            val = val | ((Red & ColorMask) << RedShift);
            val = val | (Blue & ColorMask);
            return val;
        }
    }
    

    这样您就可以轻松创建结构,而无需摆弄位数组:

    var blue17 = new Led(true, 17, 0, 0, 127);
    var blah22 = new Led(false, 22, 15, 97, 42);
    

    并获取值:

    int blue17_value = blue17.ToInt();
    

    您可以使用 BitConverter 轻松地将 int 转换为字节数组:

    var blue17_bytes = BitConverter.GetBytes(blue17_value);
    

    我不清楚你为什么要将它作为字符串发送。

    【讨论】:

      猜你喜欢
      • 2012-06-27
      • 1970-01-01
      • 2014-08-08
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      • 2011-07-02
      • 2019-12-10
      • 1970-01-01
      相关资源
      最近更新 更多