C# 从字节中获取位
C# Get Bits from Byte
我不知道为什么在读取我的字节时会出现错误位。我遵循了此处发现的一些指示,但它不起作用。我给你看我的代码:
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) 变为“true” (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
非常难读,因为大概 10 个程序员中有 9 个不 know/don 不记得表达式的意思是
1 << (bitNumber - 1)
因为在operator precedence table中-
在<<
之前,所以当你混合运算符时,你应该使用(...)
来明确优先级。
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;
}
修改后测试运行绿色。
我不知道为什么在读取我的字节时会出现错误位。我遵循了此处发现的一些指示,但它不起作用。我给你看我的代码:
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) 变为“true” (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
非常难读,因为大概 10 个程序员中有 9 个不 know/don 不记得表达式的意思是
1 << (bitNumber - 1)
因为在operator precedence table中-
在<<
之前,所以当你混合运算符时,你应该使用(...)
来明确优先级。
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;
}
修改后测试运行绿色。