在c++中使用bitshift将两个位分别设置为0和1

vuv7lop3  于 2022-11-27  发布在  其他
关注(0)|答案(2)|浏览(147)

假设x是一个8位无符号整数,将最后两位设置为01的最有效命令是什么?因此,无论初始值是什么,最终状态都应该是x = ******01
为了设定

  • 最后一位设为1,则可以使用OR,如x |= 00000001,以及
  • 最后一位为0,可以使用AND,如x &= 11111101,即~(1<<1)

是否存在可用于同时应用这两种运算的算术/逻辑运算?
这个问题是否可以独立于特定程序的实现而进行纯逻辑运算来回答?

qni6mghb

qni6mghb1#

当然你可以把两个操作放在一个指令中。

x = (x & 0b11111100) | 1;

这至少节省了一次赋值和一次内存读/写。然而,最有可能的是,编译器无论如何都可能优化这一点,即使放入两条指令。
根据目标CPU,编译器甚至可以将代码优化为位操作指令,直接设置或重置单个位。如果变量在本地大量使用,则很可能将其保存在寄存器中。
因此,最后生成的代码可能看起来像(pseudo asm)一样简单:

load x
setBit 0
clearBit 1
store x

然而它也可以被编译成类似于

load x to R1
load immediate 0b11111100 to R2
and  R1, R2
load immediate 1 to R2
or   R1, R2
store R1 to x

要处理类似的事情,您可以查看编译器资源管理器https://godbolt.org/z/sMhG3YTx9请尝试删除-O2编译器选项,并查看优化和未优化代码之间的差异。您也可以尝试切换到不同的cpu架构和编译器

uinbv5nw

uinbv5nw2#

这对于二元位运算符是不可能的。因为第二个操作数应该允许区分“重置为0”、“设置为1”或“保持不变”。这不能在单个二进制掩码中编码。
相反,您可以使用按位三元运算符并形成表达式
x = 0b11111100 ??? x : 0b00000001 .
无论如何,一片警告:此运算符不存在。

相关问题