用C++连接比特

Shr*_*yes 5 c++ bit-manipulation

我正在开发一个卷积编码器和位打孔软件.

所以在我的程序中,每个循环都会生成一个55位长的数据.它存储在unsigned long long类型变量的前55位中.在每次迭代之后,我必须将这55位传输到无符号字符的缓冲区(缓冲区很大,大约500字节).这些位必须连续存储在此缓冲区中.(即没有间隙).这样容易连接是否有点技巧?

Jor*_*eit 5

编辑:有人正确地向我指出,因为我通过 a 对 char-buffer 进行别名uint64_t*,所以我违反了严格的别名规则,并且由于字节序的差异也容易受到错误的影响。不过,如果您对自己的平台有一定的保证,这可能仍然有效。不过,可以通过使用 64 位元素的缓冲区(而不是单个字节)来解决这个问题。

如果您想要一个不依赖于任何外部库的准系统算法,您可以使用下面的代码片段。请注意,bitset 仅用于显示结果并确保其有效。

作为测试,我定义了一个由 54 个连续 1 和后跟 0 组成的 55 位模式。64 位值 ( x) 中的其余 9 位也为零。该缓冲区是一个 500 字节的字符数组,我在uint64_t*. 该算法跟踪当前 64 位块 ( currentBlock) 以及该块内的当前位 ( currentBit)。它执行以下操作:

  1. 移位位模式,使其从当前位位置开始。
  2. 将结果与当前 64 位块进行或运算。这意味着位模式的第一部分连接到当前块的剩余部分。例如,在第二次迭代中,当第一个块的前55位被填充时,剩余的9位将被占用。
  3. 更新currentBit变量。
  4. 检查是否currentBlock溢出,如果溢出,则移动到下一个块并连接 55 位模式的其余部分。

    #include <iostream>
    #include <bitset> // only used for testing, not for the algorithm
    using namespace std;
    
    int main()
    {
        size_t nBits = 55;
    
        // 54 1's, followed by 10 0's
        uint64_t x = 0b1111111111111111111111111111111111111111111111111111110000000000;
    
        // 500 byte buffer:
        char buf8[500]{};
        uint64_t *buf = reinterpret_cast<uint64_t*>(&buf8[0]);
    
        // This would be better; use this if possible
        // uint64_t buf[100];
    
        int currentBit = 0;
        int currentBlock = 0;
    
        // concatenate the 55-bitpattern 10 times 
        for (int i = 0; i != 10; ++i)
        {
            buf[currentBlock] |= (x >> currentBit);
    
            currentBit += nBits;
            if (currentBit >= 64)
            {
                ++currentBlock;
                currentBit %= 64;
    
                buf[currentBlock] |= x << (nBits - currentBit);
            }
        }
    
        // TEST
        for (int i = 0; i != 5; ++i)
            cout << bitset<64>(buf[i]) << '\n';
    }
    
    Run Code Online (Sandbox Code Playgroud)

您可能应该概括这一点并将其封装在一个函数中。这取决于你。该程序按原样产生以下输出:

1111111111111111111111111111111111111111111111111111110111111111
1111111111111111111111111111111111111111111110111111111111111111
1111111111111111111111111111111111110111111111111111111111111111
1111111111111111111111111110111111111111111111111111111111111111
1111111111111111110111111111111111111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)

请注意每隔 55 位标记 0。