You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用位移位操作实现2字节日期编解码的C语言问题排查

问题解决:仅用移位操作完成日期的编解码

问题根源

你当前解码月、日失败的核心原因是:unsigned int在32位编译环境下为32位宽度,左移操作不会自动丢弃高位的年份数据,后续右移时会带入这些无效位,导致结果错误。

根据你的编码逻辑,16位编码的位分配如下:

  • 年份偏移值(year-1980):占据高7位(bit9 ~ bit15)
  • 月份:占据中间4位(bit5 ~ bit8)
  • 日期:占据低5位(bit0 ~ bit4)

修正后的代码方案(通用32位版本)

// Date encoding in 2-byte number
#include <stdio.h>
#include <conio.h>

typedef unsigned int uint;
#define BITS_PER_UINT (sizeof(uint) * 8)

void Showbits(uint n)  // 修正参数类型为uint,避免符号位干扰
{
    int i, k, mask;
    for (i = 15; i >= 0; i--)
    {
        mask = 1 << i;
        k = n & mask;
        printf("%c", k ? '1' : '0');
    }
}

int main()
{
    uint encd_date, date, month, year;

    year = 2022;
    month = 9;
    date = 15;
    encd_date = 512 * (year - 1980) + 32 * month + date;

    printf("\nEncoded date: %u\n", encd_date);
    printf("\nencd_date: ");
    Showbits(encd_date);

    // 年份解码:右移9位,直接提取高7位
    year = 1980 + (encd_date >> 9);

    // 月份解码:先右移5位将月份移到低4位,再通过移位清除高位无效数据
    month = encd_date >> 5;
    month = month << (BITS_PER_UINT - 4);
    month = month >> (BITS_PER_UINT - 4);

    // 日期解码:左移27位清除高27位,再右移27位保留低5位
    date = encd_date << (BITS_PER_UINT - 5);
    date = date >> (BITS_PER_UINT - 5);

    printf("\ndate: ");
    Showbits(date);
    printf("\nmonth: ");
    Showbits(month);
    printf("\nyear: ");
    Showbits(year);
    printf("\nDecoded date %u month %u year %u\n", date, month, year);

    return 0;
}

简化方案(利用16位截断)

如果确定仅使用16位存储编码结果,可以将encd_date强制转换为unsigned short,利用16位宽度自动截断高位,简化移位操作:

// 解码部分替换为:
year = 1980 + ((unsigned short)encd_date >> 9);
month = (unsigned short)(encd_date << 7) >> 12;  // 左移7位丢弃高7位年份,再右移12位提取月份
date = (unsigned short)(encd_date << 11) >> 11;  // 左移11位丢弃高11位,再右移11位提取日期

关键说明

  • 移位操作仅对unsigned类型使用逻辑移位(右移补0),确保符号位不会干扰结果。
  • 通用方案通过"移位+反移位"的组合彻底清除无关高位,适配不同宽度的unsigned int类型。
  • 简化方案依赖16位截断特性,仅适用于编码结果不超过16位的场景(你的日期编码逻辑正好符合)。

内容的提问来源于stack exchange,提问作者nascent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 12:05:31