假设x是一个8位无符号整数,将最后两位设置为01的最有效命令是什么?因此,无论初始值是什么,最终状态都应该是x = ******01。为了设定
01
x = ******01
x |= 00000001
x &= 11111101
~(1<<1)
是否存在可用于同时应用这两种运算的算术/逻辑运算?这个问题是否可以独立于特定程序的实现而进行纯逻辑运算来回答?
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架构和编译器
-O2
uinbv5nw2#
这对于二元位运算符是不可能的。因为第二个操作数应该允许区分“重置为0”、“设置为1”或“保持不变”。这不能在单个二进制掩码中编码。相反,您可以使用按位三元运算符并形成表达式x = 0b11111100 ??? x : 0b00000001 .无论如何,一片警告:此运算符不存在。
x = 0b11111100 ??? x : 0b00000001
2条答案
按热度按时间qni6mghb1#
当然你可以把两个操作放在一个指令中。
这至少节省了一次赋值和一次内存读/写。然而,最有可能的是,编译器无论如何都可能优化这一点,即使放入两条指令。
根据目标CPU,编译器甚至可以将代码优化为位操作指令,直接设置或重置单个位。如果变量在本地大量使用,则很可能将其保存在寄存器中。
因此,最后生成的代码可能看起来像(pseudo asm)一样简单:
然而它也可以被编译成类似于
要处理类似的事情,您可以查看编译器资源管理器https://godbolt.org/z/sMhG3YTx9请尝试删除
-O2
编译器选项,并查看优化和未优化代码之间的差异。您也可以尝试切换到不同的cpu架构和编译器uinbv5nw2#
这对于二元位运算符是不可能的。因为第二个操作数应该允许区分“重置为0”、“设置为1”或“保持不变”。这不能在单个二进制掩码中编码。
相反,您可以使用按位三元运算符并形成表达式
x = 0b11111100 ??? x : 0b00000001
.无论如何,一片警告:此运算符不存在。