““(整数)值&0x1,(整数)值&0x2,(整数)值&0x4,(整数)值&0x8”是什么意思?”


11

码

“值”的范围是0到15(可能的值)。何时满足这四个“如果”条件?如果我的(int)值= 2,这表示0010吗?

            if  ((int)value & 0x1) 
            {
                //statement here
            }
            if  ((int)value & 0x2) 
            {
                //statement here
            }
            if  ((int)value & 0x4) 
            {
                //statement here
            }
            if  ((int)value & 0x8) 
            {
                //statement here
            }

3
这些是位掩码,用于检查的各个位value(读if(value & 0x4)为“是valueset 的第3位(= 1))。由于您似乎在理解代码时遇到问题,因此我认为它不是您的。(以及您没有询问的事实审查),使这个问题题外话CR.SE
没人

为了更好地理解,已移植到C#的类似代码将使用该Enum.HasFlag方法测试位。请参阅:Enum.HasFlag
rwong 2014年

Answers:


12

每个数字可以表示为value = b0*2^0 + b1*2^1 + b2*2^2 + b3*2^3 + ...,每个b为01(这些是表示的位)。这是二进制表示形式。

二进制AND(&)将每个b对成对并对其执行AND。它具有以下输出:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

使用2的幂(只有一个位打开),我们可以隔离和测试各个位:

  • value & 1value为奇数{1、3、5、7、9、11、13、15} 时为true 。

  • value & 2value/2为奇数{2,3,6,7,10,11,14,15} 时为true 。

  • value & 4value/4为奇数{4,5,6,7,12,12,13,14,15} 时为true 。

  • value & 8value/8为奇数{8,9,10,11,12,13,13,14,15} 时为true 。

数字上的0x前缀表示应将其解释为十六进制数字。当您只提高到0x8时,这有点多余,但告诉维护者它可能用作位掩码。


1
该措辞可能暗示它可以扩展到所有数字,但事实并非如此:8/6是奇数,而8&6产生假。
Sjoerd 2014年

@Sjoerd,这就是为什么我说“ 2的幂”的原因
棘手怪胎

5

这些if语句检查是否设置了的特定位value

0x4例如,十六进制值的第3位从右边设置为1,所有其他位设置为0。当&对两个运算符使用binary-and运算符()时,结果将所有位都设置为,0除了两个运算符中均为1的那些位。

因此,当您进行计算时value & 0x4,您将得到二进制00000000还是二进制00000100,这取决于valueis 的第3位1还是0。第一个计算为false,第二个计算为true,因此,仅对设置了第3位的值执行if块。


1

这里有两个有趣的事情要注意。

首先,这是用于检查整数值的低4位中的每一个的通用模式。如果设置了相应的位,则满足if条件。对于值2,位模式的确为0010。

另一个更有趣的问题是为什么要(int)演员?除了在C ++中使用C-cast的不良样式外,没有整数或字符值需要此强制转换。布尔没有意义,double / float会被转换为整数临时变量,并且使用文字值来测试枚举是不寻常的。使用指针可能有意义,但这将是非常专门的用途。结论:演员表毫无意义。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.