C++ C+中的零填充数组+;

C++ C+中的零填充数组+;,c++,arrays,embedded,padding,C++,Arrays,Embedded,Padding,我有一个uint8\u t数组,包含三个字节 // 1010 1010 1011 1011 1000 0000 uint8_t command[3] = {0xAA, 0xBB, 0x80}; 现在,我想在数组左侧用7个零填充该数组,最终创建以下数组(我对第4个字节不感兴趣): P> >在C++中实现零填充的最佳方法是什么?< P>解决方案,使用 STD::BITSET : std::array<std::uint8_t, 4> left_pad(const std::array

我有一个uint8\u t数组,包含三个字节

// 1010 1010 1011 1011 1000 0000
uint8_t command[3] = {0xAA, 0xBB, 0x80};
现在,我想在数组左侧用7个零填充该数组,最终创建以下数组(我对第4个字节不感兴趣):


<> P> >在C++中实现零填充的最佳方法是什么?

< P>解决方案,使用<代码> STD::BITSET :

std::array<std::uint8_t, 4>
left_pad(const std::array<std::uint8_t, 3>& in) {
    using Bitset = std::bitset<8 * 4>;
    Bitset bitset;

    for (auto b = in.begin(); b != in.end(); ++b, bitset <<= 8)
        bitset |= Bitset{*b};
    bitset >>= 7;

    std::array<std::uint8_t, 4> out;
    for (auto b = out.rbegin(); b != out.rend(); ++b, bitset >>= 8)
        *b = (bitset & Bitset{0xFF}).to_ulong();

    return out;
}
通过GCC和
-O3
优化给出:

left_pad2(std::array<unsigned char, 3ul> const&):
        movzx   eax, BYTE PTR [rdi]
        movzx   edx, BYTE PTR [rdi+1]
        sal     rax, 8
        or      rax, rdx
        movzx   edx, BYTE PTR [rdi+2]
        sal     rax, 8
        or      rax, rdx
        add     rax, rax
        bswap   eax
        ret
left_pad2(std::array const&):
movzx eax,字节PTR[rdi]
movzx edx,字节PTR[rdi+1]
sal rax,8岁
或者rax,rdx
movzx edx,字节PTR[rdi+2]
sal rax,8岁
或者rax,rdx
加上rax,rax
bswap eax
ret

left_pad(std::array<unsigned char, 3ul> const&):
        movzx   eax, BYTE PTR [rdi]
        movzx   edx, BYTE PTR [rdi+1]
        sal     rax, 8
        or      rax, rdx
        movzx   edx, BYTE PTR [rdi+2]
        sal     rax, 8
        or      rax, rdx
        sal     rax, 8
        mov     rdx, rax
        shr     rdx, 7
        mov     BYTE PTR [rsp-1], dl
        mov     rdx, rax
        shr     rdx, 15
        mov     BYTE PTR [rsp-2], dl
        mov     rdx, rax
        shr     rax, 31
        shr     rdx, 23
        mov     BYTE PTR [rsp-4], al
        mov     BYTE PTR [rsp-3], dl
        mov     eax, DWORD PTR [rsp-4]
        ret
左键盘(std::array const&): movzx eax,字节PTR[rdi] movzx edx,字节PTR[rdi+1] sal rax,8岁 或者rax,rdx movzx edx,字节PTR[rdi+2] sal rax,8岁 或者rax,rdx sal rax,8岁 mov-rdx,rax shr-rdx,7 mov字节PTR[rsp-1],dl mov-rdx,rax shr rdx,15 mov字节PTR[rsp-2],dl mov-rdx,rax shr-rax,31岁 shr rdx,23 mov字节PTR[rsp-4],al mov字节PTR[rsp-3],dl mov eax,德沃德PTR[rsp-4] ret
C不是C++,C++不是C,我删除了TaGoYx@ Evg,我会看看文档。我只是想要一种可靠的方式,不依赖于小端/大端架构。如果端性是一个问题,你到底想做什么?如果您仅在内部使用该数组,那么我将使用一个大的
uint32\t
。任何永无止境的事情都没有了。如果您需要通过网络传输,那么数组就可以了,您有四个单字节,因此endianess没有问题,您只需要将它们按正确的顺序排列。如果您想同时使用值/数组,那么您有矛盾的需求,您必须以某种方式处理endianess(像或ntohl这样的函数只是将其隐藏起来…)。A
uint8\u t[4]
将始终取决于endianess,因为它将始终存储来自LS
0x01、0x55、0x77、,0x00
MS。这与Big-Endian 32位数字一致。但是如果你想让它等于32位的数字0x01557700,那么它就不再是一致的了,在Little Endian机器上也不起作用。谢谢你的解决方案。我只是试着调试代码。插入命令=
0b0000.0000.1111.1111.1000.0000
(0x00 0xFF 0x80)时,我得到输出
0b0000.0000.0000.0001.1111.1111.0000.0000
(0x00 0x01 0xFF 0x00)。我希望最后一个字节是0x80,而不是0x00(MSB中的1)。@Lexusminds,不清楚为什么它应该是
0x80
{0x12,0x34,0x56}
的预期输出是什么?也许我应该谈谈根本原因:我正在使用一个库来计算17位上的CRC-7。这17位由8个数据位、8个命令位和一个常量“1”组成。由于库采用字符数组作为输入,因此我需要将17位转换为零填充的24位(3字节)数组。所以保留所有17位是至关重要的,包括“1”。哦,你说得对——输出和预期一样。很抱歉-不应该在午餐后立即进行逐位计算。应该不需要在运行时将初始值写入位集。
std::array<std::uint8_t, 4>
left_pad2(const std::array<std::uint8_t, 3>& in) {
    using Bitset = std::bitset<8 * 4>;
    Bitset bitset;

    for (auto b = in.begin(); b != in.end(); ++b) {
        bitset <<= 8;
        bitset |= Bitset{*b};
    }
    bitset <<= 1;

    std::array<std::uint8_t, 4> out;
    for (auto b = out.rbegin(); b != out.rend(); ++b, bitset >>= 8)
        *b = (bitset & Bitset{0xFF}).to_ulong();

    return out;
}
left_pad2(std::array<unsigned char, 3ul> const&):
        movzx   eax, BYTE PTR [rdi]
        movzx   edx, BYTE PTR [rdi+1]
        sal     rax, 8
        or      rax, rdx
        movzx   edx, BYTE PTR [rdi+2]
        sal     rax, 8
        or      rax, rdx
        add     rax, rax
        bswap   eax
        ret
left_pad(std::array<unsigned char, 3ul> const&):
        movzx   eax, BYTE PTR [rdi]
        movzx   edx, BYTE PTR [rdi+1]
        sal     rax, 8
        or      rax, rdx
        movzx   edx, BYTE PTR [rdi+2]
        sal     rax, 8
        or      rax, rdx
        sal     rax, 8
        mov     rdx, rax
        shr     rdx, 7
        mov     BYTE PTR [rsp-1], dl
        mov     rdx, rax
        shr     rdx, 15
        mov     BYTE PTR [rsp-2], dl
        mov     rdx, rax
        shr     rax, 31
        shr     rdx, 23
        mov     BYTE PTR [rsp-4], al
        mov     BYTE PTR [rsp-3], dl
        mov     eax, DWORD PTR [rsp-4]
        ret