c++ - 将跨字节数组内容提取到 std::bitset

标签 c++

我需要从字节数组 (std::vector) 中提取内容到位集。内容可能跨越两个字节。

这是我的单元测试:

std::vector<uint8_t> val = { 0xAB, 0xCD, 0xEF }; // is 101010111100110111101111

std::bitset<4> a = extractToBitSet<4>( val, 0 ); // should be 0x0A: 1010
std::bitset<8> bc = extractToBitSet<8>( val, 4 ); // should be 0xBC: 10111100
std::bitset<12> def = extractToBitSet<12>( val, 12 ); // should be 0x0DEF: 110111101111

CPPUNIT_ASSERT( a.to_string() == "1010" );
CPPUNIT_ASSERT( bc.to_string() == "10111100" );
CPPUNIT_ASSERT( def.to_string() == "110111101111" );

unsigned long aVal = a.to_ulong();
unsigned long bcVal = bc.to_ulong();
unsigned long defVal = def.to_ulong();

CPPUNIT_ASSERT( aVal == 0x0A );
CPPUNIT_ASSERT( bcVal == 0xBC );
CPPUNIT_ASSERT( defVal == 0x0DEF );

我想到了这个解决方案:

template<size_t _Count> void reverseBitSet( std::bitset<_Count>& bitset )
{
    bool val;
    for ( size_t pos = 0; pos < _Count/2; ++pos )
    {
        val = bitset[pos];
        bitset[pos] = bitset[_Count-pos-1];
        bitset[_Count-pos-1] = val;
    }
}

template<size_t _Count> std::bitset<_Count> extractToBitSet( const std::vector<uint8_t>& data, size_t offset )
{
    std::bitset<_Count> res;

    size_t pos = 0;
    uint8_t tempVal;
    std::bitset<8> tempBitSet;

    while ( pos < _Count )
    {
        tempVal = data[ (offset + pos)/8 ];

        tempBitSet = tempVal;
        reverseBitSet( tempBitSet );
        res[pos] = tempBitSet[(offset + pos)%8];

        ++pos;
    }

    reverseBitSet( res );

    return res;
}

它有效(我的测试通过),但它似乎非常低效,因为所有这些临时位集都被创建+许多反向操作。

有没有更优雅的方式来做到这一点?

最佳答案

为什么要倒车?您可以根据您正在执行的特定操作,随时显式设置每一位。只有一个循环:

template <size_t N>
std::bitset<N> extract(std::vector<uint8_t> const& vs, size_t offset) {
    std::bitset<N> res;
    for (size_t i = 0; i < N; ++i) {
        size_t full_off = offset + i;
        auto& byte = vs[full_off / 8];
        auto bit = byte & (1 << (7 - (full_off % 8)));

        res.set(N-i-1, bit);
    }
    return res;
}

关于c++ - 将跨字节数组内容提取到 std::bitset,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39350487/

相关文章:

C++ 类包装器和放置 new

c++ - 使用 InterlockedCompareExchange 无锁

c++ - 如何为 QPainterPath 子路径着色不同?

c++ - 如何组织并行程序的正确输出?

c++ - C++中未分配对象的垃圾收集

c++ - 如何在 C/C++ 中描述指向数组的 const 指针?

c++ - 将 float 与参数内的字符串连接起来

C++ 替换字符串中的单词(文本文件)

c++ - 最小的跨平台图形用户界面库?

c++ - 让编译器将 << 视为为特定类定义的