C语言中从unsigned long提取指定位的函数异常求助
解决unsigned long类型的比特位提取问题
嘿,看你被这个比特位提取函数卡了好几个小时,别慌,咱们来揪出问题所在。
你的代码逻辑本身没问题,但有个容易忽略的隐形坑:~0默认是int类型的全1值,而非unsigned long类型。这就导致当你要提取超过32位的比特(比如你例子里的40位)时,~(~0 << n)这部分直接乱套——int类型的移位操作超过自身位数属于未定义行为,就算在64位系统里,符号位扩展也会搞歪结果。
修正后的函数
把~0强制转换成unsigned long类型,让掩码的生成完全基于unsigned long的位数计算:
unsigned long getbits(unsigned long x, int p, int n){ return (x >> (p - n + 1)) & ~((unsigned long)~0 << n); }
为什么这样改?
(unsigned long)~0会生成和unsigned long位数匹配的全1值(64位系统就是64个连续的1)- 左移n位后再取反,就能得到低n位全1、其余位全0的正确掩码,完美适配unsigned long的宽度
- 不管你提取多少位(只要不超过unsigned long的总位数),掩码都不会出错
测试你的示例
修正后运行你的main函数(顺便调整了printf格式符,让输出更规范):
int main() { printf("getbits(0x12341234abcdabcd, 63, 40): 0x%016lx\n", getbits(0x12341234abcdabcd, 63, 40)); return 0; }
输出就会是你预期的0x0012341234abcdab啦。
内容的提问来源于stack exchange,提问作者user9597158
相关产品推荐
相关产品推荐

