我有一系列的片段,比如说

0110 [1011] 1111

假设我想将myddle nybble设置为0111作为新值。
使用带有ANDOR的位置掩蔽方法,我似乎别无选择,只能先将原始值设置为0000,因为如果我尝试对AND的原始值进行OR1011设置,我就不会得到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/

10-11 23:14
查看更多