首页 > 解决方案 > 这个按位运算符的位置会改变行为吗?

问题描述

这两行代码是等价的吗?

P1->OUT &= ~(uint8_t)(1<<1);

P1->OUT &= (uint8_t)(~(1<<1));

标签: cbit-manipulationlanguage-lawyerbitwise-operatorsunsigned-integer

解决方案


这取决于 的类型P1->OUT和系统。的结果1 << 1是类型int

我正在考虑一般int n;情况1 << 1

P1->OUT &= ~(uint8_t)(n);

操作数将在(整数提升)int之前再次扩大,并且将应用于. 结果将设置所有高位 8...k。如果是 8 位宽,则可以,但如果它有更多位,则结果不是您所期望的。~~intP1->OUT

这个更糟糕:

P1->OUT &= (uint8_t)(~(n));

操作数将~再次应用于 anint并且转换为uint8_t. 现在 if~n实际上是负数(设置了它的符号位) - 如果~(1 << 1)它是负数 - 在二进制补码实现中会很好,但在 1 补码和符号和大小实现中完全不正确,因为位表示不会是一样的。


进行位旋转的正确方法是始终使用unsigned int或更宽的二进制补码数:

P1->OUT &= ~(1U << n);

或者

P1->OUT &= (~(1U << n)) & 0xFF;

避免产生有符号数字的算术转换和整数提升。


推荐阅读