从32位数值提取高低16位字:为何需用0x1FFFF掩码?
关于dsPIC平台提取32位值高低16位的代码疑问与优化
原代码中0x1FFFF掩码的问题
原代码里提取高16位时用0x1FFFF << 16作为掩码是完全冗余且容易误导的写法,实际起作用的等价于0xFFFF0000(32位下的有效掩码):
- 0x1FFFF是19位的十六进制值,左移16位后会超出32位无符号长整型的范围,在XC16编译器中会被截断为32位,最终等价于
0xFFFF0000(因为0x1FFFF << 16 = 0x1FFFF0000,减去2^32后得到0xFFFF0000)。 - 所以
My_Number & (0x1FFFF << 16)本质上就是My_Number & 0xFFFF0000,再右移16位得到高16位,结果正确,但0x1FFFF这个值完全是多余的,属于画蛇添足的写法。
更简洁合规的写法
你后来优化的代码是完全正确且更符合C语言规范的:
int main() { unsigned long My_Number = 0x6000C000; // 32位无符号值 unsigned int High_Word; // 16位无符号值 unsigned int Low_Word; // 16位无符号值 High_Word = My_Number >> 16; // 直接右移16位,获取高16位 Low_Word = My_Number; // 赋值时自动截断高16位,保留低16位 return 0; }
原理说明
- 对于无符号类型的右移操作,XC16编译器会执行逻辑右移(高位补0),所以
unsigned long类型的My_Number右移16位后,直接得到高16位的数值,赋值给unsigned int时刚好匹配16位长度。 - 当把32位的
unsigned long赋值给16位的unsigned int时,C语言标准会自动截断高16位,只保留低16位,效果和My_Number & 0xFFFF完全一致,但代码更简洁。
内容的提问来源于stack exchange,提问作者spectric
相关产品推荐
相关产品推荐

