是否可以在3个字节变量中插入三个数字?

Lio*_*ing 2 c++ bit-shift

例如,我想存储包含天,月,年的日期.

  • 天 - > 31,月 - > 12,年 - > 99.

我想存储31,12,99在一个变量,将使用移位运算符<<>>操作它.

我试图做的:

short date = 0;
date = 31; // day
date << 5;
date = 12; // month
date << 7;
date = 99; // year
printf("date: %d\n", date >> 15); // print the first value
Run Code Online (Sandbox Code Playgroud)

但结果是0.我不知道这个想法本身是否可行.

小智 5

你的意思是<<=,不是<<.

也就是说,您的代码还有另外两个问题:

  • 你想要一个无符号变量; 有符号的整数在转移时会有惊人的行为.(至少,如果你认为整数是一个比特序列,它们会这样做)
  • 如果你想要一个16位类型,你应该使用int16_tuint16_t,而不是希望short是正确的大小.

你想要这样的东西

static inline uint16_t pack_date(unsigned day, unsigned month, unsigned year)
{
    // Consider inserting some checking here to make sure the numbers
    // are in their expected ranges

    return (day << 11) | (month << 7) | year;
}

static inline uint16_t get_day(uint16_t packed_value)
{
    return packed_value >> 11;
}

static inline uint16_t get_month(uint16_t packed_value)
{
    return (packed_value >> 7) & 0xf;
}

static inline uint16_t get_year(uint16_t packed_value)
{
    return packed_value & 0x7f;
}
Run Code Online (Sandbox Code Playgroud)


πάν*_*ῥεῖ 5

是的,有可能这样做.我会使用适当的方法union来掩盖值区域:

union mydate_struct {
    struct {
        uint16_t day : 5;    // 0 - 31
        uint16_t month : 4;  // 0 - 12
        uint16_t year : 7;   // 0 - 127
    };
    uint16_t date_field;
};
Run Code Online (Sandbox Code Playgroud)

这使您的年份范围从0到127.您的决定,如果这对您的实际用例是足够的.