c - 这个按位运算符的位置会改变行为吗?
问题描述
这两行代码是等价的吗?
P1->OUT &= ~(uint8_t)(1<<1);
P1->OUT &= (uint8_t)(~(1<<1));
解决方案
这取决于 的类型P1->OUT
和系统。的结果1 << 1
是类型int
。
我正在考虑一般int n;
情况1 << 1
在
P1->OUT &= ~(uint8_t)(n);
操作数将在(整数提升)int
之前再次扩大,并且将应用于. 结果将设置所有高位 8...k。如果是 8 位宽,则可以,但如果它有更多位,则结果不是您所期望的。~
~
int
P1->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;
避免产生有符号数字的算术转换和整数提升。
推荐阅读
- python - 如何在python的特定区域插入json代码?
- python - 如何将标签与 tkinter 文本小部件中的文本一起保存?
- node.js - 无服务器:Lambda 仅在控制台/ Lambda 间歇性行为发生更改后才开始工作
- python - 使用 MongoEngine 在应用程序启动时定义集合名称的正确方法是什么?
- java - 使用 tomcat 时出现 java.io.FileNotFoundException
- binary-search - 二进制搜索模板 Leetcode,它的含义是什么?
- haskell - 如何从 Golang 调用 Haskell 函数?
- javascript - 将javascript数组数据传递给php并使用它来更改if else语句中的数据
- django - 使用 Django DRF 在 ArrayModelField 中进行 POST 和 PATCH 操作
- java - 允许在 Android webview 中导航