16bit数据二进制数据流转14bit数据流

有一批固定数量的数据,每个数据占用14bit,在代码中存储时使用unsigned short,现在需要将16bit的数据转换为14bit,如下示例:

img

编程实现将16bit数据转换为14bit,输入为unsigned short类型,输出为unsigned char类型,下面的代码比较粗暴,想请教网友有没有更简单的方式

    unsigned short psrc[] = {0x3245, 0x0657, 0x2671, 0x1546};
    unsigned char pdst[7];
    unsigned char src[8] = {0};
    int index = 0;

    for(int i=0;i<sizeof(psrc)/sizeof(psrc[0]); ++i){
        src[index++] = (psrc[i] & 0xff);
        src[index++] = ((psrc[i] >> 8 )& 0xff);
    }
    index=0;
    for(int i=0;i<8;i+=8){
        pdst[index++] = src[i];

        pdst[index++] = (src[i+1] & 0x3f) | (src[i+2] << 6);

        pdst[index++] = (src[i+2]&0xfc) >> 2 | (src[i+3] << 6);

        pdst[index++] = ((src[i+3]&0x3c) >> 2)  | (src[i+4] << 4);

        pdst[index++] = (src[i+4] >> 4) | (src[i+5] << 4);

        pdst[index++] = (src[i+5] >> 4) | (src[i+6] << 2);

        pdst[index++] = (src[i+6] >> 6) | (src[i+7] << 2);
    }

考虑一下bitset

#include <bitset>
#include <cstring>

#define TRANCEBIT 14

const uint16_t psrc[] = {0x3245, 0x0657, 0x2671, 0x1546};

unsigned char
    pdst[((sizeof(psrc) / sizeof(uint16_t)) * TRANCEBIT / 8) +
         (((sizeof(psrc) / sizeof(uint16_t)) * TRANCEBIT % 8) ? 1 : 0)];

int main()
{
    const size_t size = sizeof(psrc) / sizeof(uint16_t);

    std::bitset<TRANCEBIT * size> temp;

    for (int i = 0; i != size; ++i)
    {
        for (int j = 0; j != TRANCEBIT; ++j)
        {
            temp.set(i * TRANCEBIT + j, (psrc[i] >> j) & 1);
        }
    }

    memcpy(pdst, &temp, sizeof(pdst));

    for (unsigned char i : pdst)
    {
        printf("0x%x ", i);
    }

    return 0;
}

将16位数据分割成高8位和低6位。然后,将高8位左移6位并与低6位进行按位或操作,以合并为一个8位无符号字符,将转换后的8位数据以16进制格式存储即可

  • 这篇博客: 4.3 C语言的高级用法以及易错点中的 14、8bit 16bit 32bit之间的相互转换 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • //32bit ->16bit 
    void Uint32_to_uint16(int32_t *source,uint16_t *target,uint8_t len){
    	uint8_t tf_i;
    	for(tf_i=0;tf_i<len;tf_i++)
      {
    		*(target+2*tf_i)  = (*(source+tf_i))>>16;
    		*(target+2*tf_i+1)= (*(source+tf_i));
      }
    }
    
    //8bit转32bit
    uint32_t beBufToUint32(uint8_t *_pBuf)
    {
        return ( _pBuf[0] | ((uint32_t)_pBuf[1] << 8) | ((uint32_t)_pBuf[2] << 16) | ((uint32_t)_pBuf[3] << 24));
    }
    
    //其他同理