我有一系列的片段,比如说
0110 [1011] 1111
假设我想将myddle nybble设置为
0111
作为新值。使用带有
AND
或OR
的位置掩蔽方法,我似乎别无选择,只能先将原始值设置为0000
,因为如果我尝试对AND
的原始值进行OR
或1011
设置,我就不会得到0111
的所需结果。我是否应该使用另一个逻辑运算符来获得所需的效果?还是我每次都要做两次手术?
在善意的帮助下,结果是:
inline void foo(Clazz* parent, const Uint8& material, const bool& x, const bool& y, const bool& z)
{
Uint8 offset = x | (y << 1) | (z << 2); //(0-7)
Uint64 positionMask = 255 << offset * 8; //255 = length of each entry (8 bits), 8 = number of bits per material entry
Uint64 value = material << offset * 8;
parent->childType &= ~positionMask; //flip bits to clear given range.
parent->childType |= value;
}
……我相信这会有进一步的改进,但这是(半)可读的版本。
最佳答案
如果您碰巧已经知道位的当前值,则可以执行异或:
0110 1011 1111
^ 0000 1100 0000
= 0110 0111 1111
(其中,
1100
需要首先作为当前位和所需位之间的异或计算)。当然,这仍然是两次行动。不同的是,您可以在某些情况下预计算第一个异或。
除了这个特例,没有别的办法了。基本上需要表示3种状态:设置为1、设置为0、不更改。不能用一个二进制操作数完成此操作。
关于c++ - 我可以设置一个位序列而不重置先前的值吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8141583/