位移位操作的类型转换问题:合并16位寄存器值为32位变量结果异常
问题原因
你的问题根源于C语言的运算符优先级规则:加法运算符+的优先级高于移位运算符>>、<<,所以你写的sum表达式实际执行逻辑和预期完全不符。
你原本的写法:
uint32_t sum = ((uint32_t)id0)>>7 + ((uint32_t)id1)<<9;
会被编译器按优先级解析为:
uint32_t sum = ( ((uint32_t)id0) >> (7 + ((uint32_t)id1)) ) << 9;
先计算7 + id1得到值0xABD4,再将id0右移这么多位。对于32位无符号整数来说,移位位数超过31时多数平台返回结果为0,最后左移9位依然是0,这就是你得到错误结果的原因。
解决方案
只需要给两个移位运算分别加括号,保证移位先于加法执行即可,不需要额外声明中间变量:
uint32_t sum = ( ((uint32_t)id0) >> 7 ) + ( ((uint32_t)id1) << 9 );
如果两个移位后的位段没有重叠,你也可以用按位或|代替加法,更符合位合并的使用场景,结果完全一致:
uint32_t sum = ( ((uint32_t)id0) >> 7 ) | ( ((uint32_t)id1) << 9 );
修改后的代码运行得到的sum结果就是你预期的0x01579a9c。
内容的提问来源于stack exchange,提问作者Puck
相关产品推荐
相关产品推荐

