【问题标题】:C# Get Bits from ByteC# 从字节中获取位
【发布时间】:2021-01-27 10:10:39
【问题描述】:

我不知道为什么在读取我的字节时我得到了错误的位。我遵循了一些在这里找到的迹象,但它不起作用。我给你看我的代码:

byte[] byte22And23 = _packet.ReadBytes(2);
DataFromGTAPackets.Packet8.ControlFlags.rightEngineSmoke = _packet.GetBit(byte22And23[0], 0);
DataFromGTAPackets.Packet8.ControlFlags.leftEngineSmoke = _packet.GetBit(byte22And23[0], 1);
DataFromGTAPackets.Packet8.ControlFlags.rightEngineFire = _packet.GetBit(byte22And23[0], 2);
DataFromGTAPackets.Packet8.ControlFlags.leftEngineFire = _packet.GetBit(byte22And23[0], 3);
DataFromGTAPackets.Packet8.ControlFlags.rightRotorFail = _packet.GetBit(byte22And23[0], 4);
DataFromGTAPackets.Packet8.ControlFlags.leftRotorFail = _packet.GetBit(byte22And23[0], 5);
etc...
public bool GetBit(byte b, int bitNumber)
    {
        bool bit = (b & (1 << bitNumber - 1)) != 0;
        return bit;
    }

我的字节 22 的值为 2,它是:00000010。我的字节 23 的值为 0。当我使用此代码读取字节 22 时,我的第三个变量(rightEngineFire)变得“真”(1 )。毫无意义,显然是错误的。但是不知道怎么回事。

谢谢!

【问题讨论】:

  • 如果bitNumber == 0,你会转移多少?

标签: c# byte bit


【解决方案1】:

你的GetBit 方法认为位数是 1...32,而不是 0...31。

简单测试:

bool b1 = GetBit(1, 0); // false
bool b2 = GetBit(1, 1); // true

您应该将方法更改为

public static bool GetBit(byte b, int bitNumber)
{
    bool bit = (b & (1 << bitNumber)) != 0;
    return bit;
}

或者你可以写:

DataFromGTAPackets.Packet8.ControlFlags.rightEngineSmoke = _packet.GetBit(byte22And23[0], 1);

但是在 C 派生语言(C# 是 C 派生语言)中,我们从 0 开始计数,所以第一个解决方案更好(对我来说)。

作为旁注:

1 << bitNumber - 1

很不可读,因为可能有十分之九的程序员不知道/不记得这个表达式的意思

1 << (bitNumber - 1)

因为operator precedence table-&lt;&lt;之前,所以当你混合运算符时你应该使用(...)来明确优先级。

【讨论】:

    【解决方案2】:

    GetBit() 的实现是错误的,你可以通过下面的测试来检查:

    [TestMethod]
    public void MyTestMethod()
    {
        var byte22And23 = new byte[] { 2, 0 };
        var sb = new StringBuilder();
        for (int i = 7; i >=0; i--)
        {
            var r = GetBit(byte22And23[0], i);
            sb.Append((r) ? "1" : "0");
        }
    
        // result: 00000100
        Assert.AreEqual("00000010", sb.ToString());
    }
    

    看起来GetBit() 中不需要-1,因为您索引的是基于 0 而不是基于 1 的位:

    public bool GetBit(byte b, int bitNumber)
    {
        // no need of -1 here ------------ˇ
        bool bit = (b & (1 << bitNumber - 1)) != 0;
        return bit;
    }
    

    修改后测试运行绿色。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-21
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      相关资源
      最近更新 更多