我正在尝试编写一个支持12位输入和输出的小应用程序。我有输出工作,通过使用每个字12位能够将数字4095到0写入文件。本质上,输入应该读取该文件(因此,读取数字4095到0)。输入文件必须有一个32字节的缓冲区(即从文件填充缓冲区,读取12位的块,保存多余的位,重新填充缓冲区并重复)。
为了测试这个,我有一个循环,将'i'从4095减少到0.在循环中我请求12Bit输入类给我下一个12位数。理想情况下,这应该等同于'i'。
我相信我有逻辑工作,但由于某种原因,一旦我到达4078,循环总是失败。输入类返回值3822而不是所需的4078,尽管它使用相同的逻辑和所有数字之前的工作正如所料。我知道到达缓冲区的末尾不是问题(我还没有实现该部分),因为这个数字位于缓冲区的25.5 - 27个字节。我不知道为什么它在这一点上失败了。
输入类的代码:
int IStream12Bits::fetchCode()
{
byte data[2];
cout << "fByteCount: " << fByteCount << endl;
if(!(fByteCount % 3)){
cout << "!!! START OF BYTE !!!" << endl;
data[0] = fBuffer[fByteCount];
data[1] = (fBuffer[fByteCount + 1] & 0xF0);
fByteCount++;
}
else{
cout << "!!! MIDDLE OF BYTE !!!" << endl;
data[0] = fBuffer[fByteCount];
data[1] = fBuffer[(fByteCount + 1)];
data[0] = ((data[0] & 0x0F) << 4);
int temp = data[1];
temp = temp >> 4;
data[0] = (data[0] + temp);
data[1] = (data[1] & 0xF0);
fByteCount += 2;
}
int result = 0;
fByteIndex = 0;
fBitIndex = 8;
for(int i = 0; i < 12; i++){
if(data[fByteIndex] & (1 << (fBitIndex - 1))){ //if the MSB is 1, write it to the result
result += (1 << i);
}
fBitIndex--;
//if at the end of the byte, move on to the next
if(fBitIndex == 0){
fByteIndex = 1;
fBitIndex = 8;
}
}
return result;
}
修改
全部修复。问题部分在于掩盖,部分在于我的阅读。我所要做的只是直接从fBuffer读取,因为算法是这样的,一次读取后fBitIndex将减少到4(导致下一次读取自动在一个字节的中途开始)。无需将数据屏蔽和复制到单独的数组中。原来我只是让自己变得更加复杂。
答案 0 :(得分:4)
“解码”12位值的代码太复杂了。
对于“偶数”情况,你有这样的位:
fBuffer[n] fBuffer[n+1] // var
76543210 76543210 // bit offsets
AAAAAAAA BBBB.... // value
你需要:
result
BA9876543210
AAAAAAAABBBB
请注意,“A”已向上移动4个位置,“B”向下移动4个。将其翻译为C ++:
result = (fBuffer[n] << 4) + ((fBuffer[n+1] & 0xF0)>>4);
对于“奇怪”案例:
fBuffer[n] fBuffer[n+1]
76543210 76543210 // bit offsets
....AAAA BBBBBBBB
你需要:
result
BA9876543210
AAAABBBBBBBB
请注意,这次“A”已向上移动了8个位置,“B”不需要任何移位。将其翻译为C ++:
result = ((fBuffer[n] & 0x0F) << 8) + fBuffer[n+1];
这就是解码流所需的全部内容(假设您使用的是无符号类型)。
还有一些其他东西可疑:在初始加载后我没有看到调用reload
。这是一个问题。
答案 1 :(得分:0)
啊哈,很难调试这样的东西!
data[1] = (data[1] & 0xF0)
我认为这应该说
data[1] = ((data[1] & 0x0F) << 4)
因为您已使用上一行data[1] & 0xF0
(data[1] >> 4
)。