单行与多行位运算结果不一致的原因探究
位运算结果差异的核心原因
问题里的结果差异,本质是C语言的整数提升规则和赋值时的类型截断导致的,具体拆解如下:
第一段代码分析
unsigned char byte_to_write_1 = (0xFF << 2) >> 2; // 结果0xFF
0xFF是unsigned char类型,在参与任何位运算前,会被自动提升为int类型(32位系统下对应0x000000FF)。- 左移2位后得到
0x000003FC(二进制高位全为0,低10位是1111111100),这个值完全在int的取值范围内,没有溢出或截断。 - 接着对这个
int类型的值执行右移2位,得到0x000000FF(即十进制255),最后赋值给unsigned char时,直接保留低8位的0xFF,所以最终结果是0xFF。
第二段代码分析
unsigned char byte_to_write_2 = (0xFF << 2); byte_to_write_2 = byte_to_write_2 >> 2; // 结果0x3F
- 第一步赋值:
0xFF同样先提升为int左移2位得到0x000003FC,但赋值给unsigned char时,会截断高位,仅保留低8位,也就是0xFC(二进制11111100)。 - 第二步移位:此时操作数是
unsigned char类型,右移时采用逻辑右移(高位补0),0xFC右移2位后得到0x3F(二进制00111111),所以最终结果是0x3F。
你的猜测完全正确:单行位运算时,所有操作都是在提升后的更大数据类型(int)上完成的,没有中途截断高位,因此移位后能恢复原始的全1位;而分两步操作时,第一步赋值已经截断了高位,后续移位只能基于截断后的值执行,自然得到不同结果。
内容的提问来源于stack exchange,提问作者Seth Rossman
相关产品推荐
相关产品推荐

