关于枚举和按位运算

发布于 2024-12-11 05:30:20 字数 453 浏览 0 评论 0原文

也许问题是如此简单......

有一个枚举定义:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

蓬勃野心 2024-12-18 05:30:20

最终,此代码检查 uop->flags 变量中的单个位(FCTRL 标志)是否打开。

但这里有一些解释:

代码 if(X) 隐式地检查 X 是否为“true”值。
对于整数,0 是唯一的“假”值,其他所有值都是“真”。

因此,您的代码相当于:

if (0 != (uop->flags & FCTRL))

现在,这是什么意思?

& 运算符执行“按位与”,这意味着左侧的每个位与右侧的相应位进行与运算。

因此,如果我们以二进制写出两个操作数:

uop->flags      1010 1010  (example)

FCTRL           0100 0000

在本例中,如果对每对位执行“AND”,您将得到结果:

result          0000 0000

其计算结果为 false,实际上在该示例中,uop-> ;flags 值没有设置 FCTRL 标志。

现在这是另一个示例,其中设置了标志 is

uop->flags      1110 1010  (example)

FCTRL           0100 0000

相应的 AND 运算结果:

result          0100 0000

该结果非零,因此为“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:

uop->flags      1010 1010  (example)

FCTRL           0100 0000

In this example, if you perform an "AND" on each pair of bits, you get the result:

result          0000 0000

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:

uop->flags      1110 1010  (example)

FCTRL           0100 0000

The corresponding ANDed result:

result          0100 0000

This result is non-zero, therefore "true", triggering your if statement.

薔薇婲 2024-12-18 05:30:20

这是一个枚举,用于定义操作的多个“标志”。您可以通过以下事实来推断这一点:每个定义的值都是 2 的精确幂,因此由值的单个位(“标志”)表示。

这种类型枚举的优点是,您可以使用按位或组合任意数量的标志:

uop->flags = FMEM | FLOAD | FRET; // sets the three corresponding flags

您给出的使用按位与的条件

uop->flags & FCTRL

当且仅当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:

uop->flags = FMEM | FLOAD | FRET; // sets the three corresponding flags

The condition you give, which uses bitwise AND

uop->flags & FCTRL

is true if and only if when the FCTRL flag is set, i.e. when the 7th bit of uop->flags is set. This is because FCTRL == 0x040 == binary 01000000.

_蜘蛛 2024-12-18 05:30:20

当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.

捶死心动 2024-12-18 05:30:20

当该位被设置时,条件为真。 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.

匿名的好友 2024-12-18 05:30:20

由于枚举类型使用二进制数字的位置(即单位、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.

蒗幽 2024-12-18 05:30:20

在这种情况下,每个下一个枚举项都会左移 1 位,因此只需检查 variable & 是否设置了某些标志即可合法地检查是否设置了某个标志。标志==真。但是,如果我们想设置多位标志模式怎么办?例如-

enum {
     #ifdef __GNUC__ // cool in GCC we can use binary constants
        myFlag = 0b1010
     #else           // otherwise fallback into integral constant mode
        myFlag = 10
     #endif
}

何时如何检查我们的变量 X 是否设置了此标志?我们不能只是做
X & myFlag == true,因为例如 0b1000 & myFlag == true0b0010 & myFlag == true - 但 0b1000 和 0b0010 都没有设置我们的两个位!出于这个原因,我更喜欢对位掩码进行全面检查,它可以在枚举中定义多位模式:

#define IS_BIT_MASK_SET(variable,flag) ((variable & flag) == flag)

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-

enum {
     #ifdef __GNUC__ // cool in GCC we can use binary constants
        myFlag = 0b1010
     #else           // otherwise fallback into integral constant mode
        myFlag = 10
     #endif
}

when how to check if our variable X has this flag set ? We can't just do
X & myFlag == true, because for example 0b1000 & myFlag == true and 0b0010 & 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:

#define IS_BIT_MASK_SET(variable,flag) ((variable & flag) == flag)

hth!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文