关于枚举和按位运算
也许问题是如此简单......
有一个枚举定义:
enum uop_flags_enum {
FICOMP = 0x001,
FLCOMP = 0x002,
FFCOMP = 0x004,
FMEM = 0x008,
FLOAD = 0x010,
FSTORE = 0x020,
FCTRL = 0x040,
FCALL = 0x080,
FRET = 0x100,
FCOND = 0x200
};
代码中的某个地方有:
if (uop->flags & FCTRL)
这个条件何时为真,何时不为真?
Maybe the question is so simple...
There is an enum definition:
enum uop_flags_enum {
FICOMP = 0x001,
FLCOMP = 0x002,
FFCOMP = 0x004,
FMEM = 0x008,
FLOAD = 0x010,
FSTORE = 0x020,
FCTRL = 0x040,
FCALL = 0x080,
FRET = 0x100,
FCOND = 0x200
};
Somewhere in the code there is:
if (uop->flags & FCTRL)
When this condition is true and when it is not?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
最终,此代码检查 uop->flags 变量中的单个位(FCTRL 标志)是否打开。
但这里有一些解释:
代码
if(X)
隐式地检查 X 是否为“true”值。对于整数,0 是唯一的“假”值,其他所有值都是“真”。
因此,您的代码相当于:
if (0 != (uop->flags & FCTRL))
现在,这是什么意思?
&
运算符执行“按位与”,这意味着左侧的每个位与右侧的相应位进行与运算。因此,如果我们以二进制写出两个操作数:
在本例中,如果对每对位执行“AND”,您将得到结果:
其计算结果为 false,实际上在该示例中,uop-> ;flags 值没有设置 FCTRL 标志。
现在这是另一个示例,其中设置了标志 is:
相应的 AND 运算结果:
该结果非零,因此为“true”,触发您的
if
语句。Ultimately, this code is checking if a single bit (the FCTRL flag) is turned on in the
uop->flags
variable.But here's some explanation:
Implicitly, the code
if(X)
checks for X being a "true" value.For integers, 0 is the only "false" value and everything else is "true".
Therefore your code is equivalent to:
if (0 != (uop->flags & FCTRL))
Now, what does that mean?
The
&
operator performs a "bitwise AND", which means each bit of the left-hand-side is ANDed with the corresponding bit on the right-hand-side.So if we wrote out our two operands in binary:
In this example, if you perform an "AND" on each pair of bits, you get the result:
Which evaluates to false, and indeed in that example the
uop->flags
value does not have the FCTRL flag set.Now here's another example, where the flag is set:
The corresponding ANDed result:
This result is non-zero, therefore "true", triggering your
if
statement.这是一个枚举,用于定义操作的多个“标志”。您可以通过以下事实来推断这一点:每个定义的值都是 2 的精确幂,因此由值的单个位(“标志”)表示。
这种类型枚举的优点是,您可以使用按位或组合任意数量的标志:
您给出的使用按位与的条件
当且仅当
FCTRL 标志被设置,即当第 7 个
uop->flags
位被设置。这是因为 FCTRL == 0x040 == 二进制 01000000。This is an enum used to define a number of "flags" for an operation. You can deduce this by the fact that every defined value is an exact power of two, and because of this is represented by a single bit ("flag") of a value.
The advantage of this type of enum is that you can combine as many of the flags as you want by using bitwise OR:
The condition you give, which uses bitwise AND
is true if and only if when the
FCTRL
flag is set, i.e. when the 7th bit ofuop->flags
is set. This is because FCTRL == 0x040 == binary 01000000.当uop->flags中对应于FCTRL(0x040)的位被设置时,条件为真。 '&'是按位与,实际上屏蔽了除 FCTRL 设置的位之外的所有位。
When the bit corresponding to FCTRL (0x040) is set in uop->flags, the condition is true. '&' is a bitwise AND in effect masking all bits but the ones set by FCTRL.
当该位被设置时,条件为真。 0x40 是 1000000,因此当
flags
中的第 7 位被设置时 - 它将为 true。The condition is true when the bit is set. 0x40 is 1000000, so when the 7th bit in
flags
is set - it will be true.由于枚举类型使用二进制数字的位置(即单位、2、4、8、16 等),并且操作执行逻辑与。如果设置了该位,则该值将不会为零(真),否则将为假。
As the enumerate type is making use of the position of binary digits (i.e. units, 2, 4, 8, 16 etc) and the operation does a logic and. If that bit place is set the value will not be zero (true) otherwise it will be false.
在这种情况下,每个下一个枚举项都会左移 1 位,因此只需检查
variable & 是否设置了某些标志即可合法地检查是否设置了某个标志。标志==真
。但是,如果我们想设置多位标志模式怎么办?例如-何时如何检查我们的变量 X 是否设置了此标志?我们不能只是做
X & myFlag == true
,因为例如0b1000 & myFlag == true
和0b0010 & myFlag == true
- 但 0b1000 和 0b0010 都没有设置我们的两个位!出于这个原因,我更喜欢对位掩码进行全面检查,它可以在枚举中定义多位模式:hth!
In this case each next enum item is shifted by 1 bit left, so it is legal to check if some flag is set by just checking if
variable & flag == true
. However what if we want to set multi-bit flag pattern ? For example-when how to check if our variable X has this flag set ? We can't just do
X & myFlag == true
, because for example0b1000 & myFlag == true
and0b0010 & myFlag == true
- but neither 0b1000 nor 0b0010 has our TWO bits set ! For this reason I prefer full checking of bitmask which lets to define multi-bit patterns in enum:hth!