我正在尝试编写一个支持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(导致下一次读取自动在一个字节的中途开始).无需将数据屏蔽和复制到单独的数组中.原来我只是让自己变得更复杂.
解决方法
您的“解码”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];
这就是解码流所需的全部内容(假设您使用的是无符号类型).
还有一些其他东西是可疑的:我没有看到在初始加载后重新加载调用.这是一个问题.