C/C++ packing signed char into int

前端 未结 6 1384
耶瑟儿~
耶瑟儿~ 2021-01-19 15:47

I have need to pack four signed bytes into 32-bit integral type. this is what I came up to:

int32_t byte(int8_t c) { return (unsigned char)c; }

int pack(cha         


        
6条回答
  •  囚心锁ツ
    2021-01-19 16:45

    This is based on Grant Peters and Joey Adams' answers, extended to show how to unpack the signed values (the unpack functions rely on the modulo rules of unsigned values in C):

    (As Steve Jessop noted in comments, there is no need for separate pack_s and pack_u functions).

    inline uint32_t pack(uint8_t c0, uint8_t c1, uint8_t c2, uint8_t c3)
    {
        return ((uint32_t)c0 << 24) | ((uint32_t)c1 << 16) |
            ((uint32_t)c2 << 8) | (uint32_t)c3;
    }
    
    inline uint8_t unpack_c3_u(uint32_t p)
    {
        return p >> 24;
    }
    
    inline uint8_t unpack_c2_u(uint32_t p)
    {
        return p >> 16;
    }
    
    inline uint8_t unpack_c1_u(uint32_t p)
    {
        return p >> 8;
    }
    
    inline uint8_t unpack_c0_u(uint32_t p)
    {
        return p;
    }
    
    inline uint8_t unpack_c3_s(uint32_t p)
    {
        int t = unpack_c3_u(p);
        return t <= 127 ? t : t - 256;
    }
    
    inline uint8_t unpack_c2_s(uint32_t p)
    {
        int t = unpack_c2_u(p);
        return t <= 127 ? t : t - 256;
    }
    
    inline uint8_t unpack_c1_s(uint32_t p)
    {
        int t = unpack_c1_u(p);
        return t <= 127 ? t : t - 256;
    }
    
    inline uint8_t unpack_c0_s(uint32_t p)
    {
        int t = unpack_c0_u(p);
        return t <= 127 ? t : t - 256;
    }
    

    (These are necessary rather than simply casting back to int8_t, because the latter may cause an implementation-defined signal to be raised if the value is over 127, so it's not strictly portable).

提交回复
热议问题