C++中的12位输入

9
我正在尝试编写一个小应用程序,使其能够进行12位输入和输出。我已经让输出正常工作,通过每个字使用12位,可以将数字4095到0写入文件。基本上,输入应该读取该文件(因此,读取数字4095到0)。输入文件必须有一个32字节的缓冲区(即从文件中填充缓冲区,读取12位块,保存多余的位数,重新填充缓冲区并重复)。
为了测试这一点,我有一个循环,从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(导致下一次读取自动开始于字节的中间)。不需要进行掩码和将数据复制到单独的数组中。结果发现我只是让问题变得更加复杂了。

2个回答

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。这是个问题。


0
啊哈,像这样调试起来很困难!
data[1] = (data[1] & 0xF0)

我觉得这应该是这么说的

data[1] = ((data[1] & 0x0F) << 4)

由于您在上一行中已经使用了data[1] & 0xF0(作为data[1] >> 4),因此:


顺便提一下,将移位操作与有符号类型结合使用有点危险。 - Jordy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接