我尝试将17位数据组移动到字节数组时遇到了一些问题。我不想一步一步地走,但我无法弄清楚逻辑循环
我需要这种方式,因为我打算通过在合并它们之后将所有字节值相加来计算校验和。
所以这就是我正在努力的方向。
我有16个字节的数组。数组的前3个字节包含我之后的17位。 ([0]
的8位,[1]
的8位和[2]
的MSB。)
我需要将这16个17位值移动到一个单独的字节数组中。
第一个很简单:
int index = 0;
myArray[index++] = driverData[driver][0]; //First byte
myArray[index++] = driverData[driver][1]; //Second byte
myArray[index] = (driverData[driver][2] & 0x80) << 7; //First bit of the third byte.
从这里开始,尝试任何类型的循环都会越来越难以移动它们。
driver++;<br>
//Take the 7 MSBs from the data array.
myArray[index++] |= (byte)(driverData[driver][0] & 0x7e >> 1);
//This leaves a single bit left over on driverData[driver][0].
myArray[index] = (byte)(driverData[driver][1] & 0x1 << 7);
我想你得到的照片。我做错了吗?有人能指出我正确的方向吗?
答案 0 :(得分:2)
听起来你有一个足够大的素数循环,使个别情况的编码成为一个坏主意。这是一个经典的包装问题。你需要一个循环遍历目的地的循环,以及一些内部代码,它们可以获得更多的数据包。您的打包代码应该知道上次迭代可以使用多少位,需要多少位,并且如果源指针不够,应该能够增加源指针。
答案 1 :(得分:2)
好的,所以这看起来很有效。我可能需要更多地测试它,但这似乎给了我迄今为止所期望的结果。我确信我能以某种方式做得更好。
// ... //
void foo()
{
//Lets start by getting all the 17bit values from each driver for the board.
int bitIndex = 7;
int byteIndex = 0;
int stopIndex = chipIndex + GetChipCount();
//Now we start the shiftyness.
for (int driver = chipIndex; driver < stopIndex; driver++) {
int userBits =
(driverData[driver][0] & 0xff) << 9 | (driverData[driver][1]
& 0xff)
<< 1 | (driverData[driver][2] & 0x80) >> 7;
AddBitsToArray(userBits, ref bitIndex, ref byteIndex);
}
}
/// <summary>
/// Takes the 17 bits, and adds them to the byte array.
/// </summary>
private void AddBitsToArray(int userBits, ref int bitIndex, ref int byteIndex)
{
int bitCount = 17;
while (bitCount > 0) {
//First 8 bytes.
checksumBytes[byteIndex] |=
(byte) (((userBits & bitValue(bitCount - 1)) >>
(bitCount - 1)) << bitIndex);
//Move up the bit index to be written to.
bitIndex--;
//Decrement the number of bits left to shift.
bitCount--;
//If we have gone past the 8th bit, reset the bitIndex and increment the byteIndex.
if (bitIndex >= 0)
continue;
bitIndex = 7;
byteIndex++;
}
}
/// <summary>
/// Returns the value of a single bit at the given index.
/// </summary>
private int bitValue(int bitIndex)
{
return (int)(Math.Pow(2, bitIndex));
}
答案 2 :(得分:1)
这是我想出的。该方法的第一部分只是设置一些虚假的输入数据,所以删除它并根据需要添加参数。 OutputData
数组不必要地大,但我没有花时间计算它的实际长度。
我使用170作为输入值10101010
并且有助于验证。
private void BitShift17()
{
const int NumChunks = 16;
byte[] DriverData = new byte[]
{
170,
170,
170
};
byte[][] InputData = new byte[NumChunks][];
for (int n = 0; n < NumChunks; n++)
InputData[n] = DriverData;
byte[] OutputData = new byte[NumChunks * 3]; // Unnecessarily large
int OutputIndex = 0;
int BitPosition = 0;
for (int Driver = 0; Driver < InputData.Length; Driver++)
{
for (int InputIndex = 0; InputIndex < 3; InputIndex++)
{
byte InputByte = InputIndex == 2 ? (byte)(InputData[Driver][InputIndex] & 128) : InputData[Driver][InputIndex];
if (BitPosition == 0)
{
OutputData[OutputIndex] = InputByte;
if (InputIndex == 2)
BitPosition++;
else
OutputIndex++;
}
else
{
if (InputIndex == 2)
{
OutputData[OutputIndex] |= (byte)(InputByte >> BitPosition);
BitPosition++;
}
else
{
OutputData[OutputIndex] |= (byte)(InputByte >> BitPosition);
OutputIndex++;
OutputData[OutputIndex] = (byte)(InputByte << 8 - BitPosition);
}
}
}
if (BitPosition > 7) BitPosition = 0;
}
}