位掩码问题?

我有以下内容:

public static final int LIMIT_ONE = 1; public static final int TRADEABLE = (1 << 1); public static final int SELLABLE = (1 << 2); public static final int STORABLE = (1 << 3); public static final int STORABLE_IN_WH = (1 << 4); public static final int STORABLE_IN_LEGION_WH = (1 << 5); public static final int BREAKABLE = (1 << 6); public static final int SOUL_BOUND = (1 << 7); public static final int UNK9 = (1 << 8); public static final int UNK10 = (1 << 9); public static final int UNK11 = (1 << 10); public static final int CAN_COMPOSITE_WEAPON = (1 << 11); public static final int BLACK_CLOUD_TRADERS = (1 << 12); public static final int CAN_SPLIT = (1 << 13); public static final int UNK15 = (1 << 14); public static final int UNK16 = (1 << 15); 

我想了解如何计算得出以下结果,例如: 12414

关于bitmask如何工作,我真的很无能为力,如果任何人可以给出一些提示并解释它是如何进行的,我会非常感激。

表达式(1 << n)等于2增加到n的幂。

当你写(1 << n) | (1 << m) (1 << n) | (1 << m)只要nm不同,这与(1 << n) + (1 << m)相同。 因此,如果您愿意,可以通过简单的添加来考虑它。

二进制数1241411000001111110因此它是以下标志的总和(或按位OR):

可交易1 << 1 = 2
可卖1 << 2 = 4
可存储1 << 3 = 8
 STORABLE_IN_WH 1 << 4 = 16
 STORABLE_IN_LEGION_WH 1 << 5 = 32
 BREAKABLE 1 << 6 = 64
 BLACK_CLOUD_TRADERS 1 << 12 = 4096
 CAN_SPLIT 1 << 13 = 8192
 ========================================
                         总计= 12414

注意,当从右向左读取时,包括的标志对应于在12414的二进制表示中设置的位。

二进制 12414是:

 Binary number: 1 1 0 0 0 0 0 1 1 1 1 1 1 0 ------------------------------------------------------- Bit positions: 13 12 11 10 9 8 7 6 5 4 3 2 1 0 

查看哪些位是1.这些是在位掩码中设置的标志,它是通过使用按位OR运算符组合标志创建的:

 bitmask = TRADEABLE | SELLABLE | STORABLE | STORABLE_IN_WH | STORABLE_IN_LEGION_WH | BREAKABLE | BLACK_CLOUD_TRADERS | CAN_SPLIT; 

为了进一步解释这一点, STORABLE = (1 << 3); 意味着STORABLE等于第一个(二进制1,仅在位位置0下降)向左移位3个位置。 请注意, STORABLE = Math.pow(2, 3); 会是等同的。 因为标志之间没有任何位重叠,所以我们可以将它们全部组合成一个int,然后将它们分开。

我们可以使用按位AND运算符来检查是否存在标志,如果设置了标志,它将返回非零值,如果未设置标志,则返回零值:

 if(bitmask & TRADEABLE != 0) { // This item can be traded } else { // This item cannot be traded } 

我们可以设置,清除或切换这样的标志:

 bitmask |= TRADEABLE; // Sets the flag using bitwise OR bitmask &= ~TRADEABLE; // Clears the flag using bitwise AND and NOT bitmask ^= TRADEABLE; // Toggles the flag using bitwise XOR 

a << bb值中的位向左移位,用零填充右边的新位。 1 << n等于只有第n位(从右边0开始计数)的整数,相当于2 n

12414是二进制的11000001111110。 因此,它是通过总结下面列出的常数产生的。 您可以通过查看右侧的位1来设置它,因此TRADEABLE是“set”; 第7位未设置(它为0),因此SOUL_BOUND不是“设置”。 注意位数如何与声明的值(1 << n)相关联。

 TRADEABLE SELLABLE STORABLE STORABLE_IN_WH STORABLE_IN_LEGION_WH BREAKABLE BLACK_CLOUD_TRADERS CAN_SPLIT 

我不明白“如何计算得出以下结果”的问题。 (计算什么?)

要理解的主要是所有计算机值都以二进制forms存储。 任何数字都是0和1位的组合。 有些数字只有一位。

http://en.wikipedia.org/wiki/Mask_(computing

我的猜测是你拿一些数字,例如你的例子12414,并找出其中包含的属性。

例如,由于12414是二进制的11000001111110,无论它附加到什么都是可交易的,因为使用掩码对该数字进行AND运算将在第二位给出1。

在二进制中,12414是11000001111110.二进制的LIMIT_ONE是1,而<<,即bitshift运算符将零移动到左边的填充,右边为零。 因此,二进制可交易为10,依此类推,直到unk16,最终为1000000000000000.现在,您使用按位OR将这些值放在一起,这基本上在每个位置放置1,其中至少有一个操作数在该位置有一个(管道运算符'|'在大多数语言中使用)。

例:

 100 | 10 = 110 

因此,要到达12414,您需要对以下变量执行按位OR:unk16,unk15,可交易,可提供,可存储,可存储在wh中,可存储在军团中且可破坏。 每个变量中不同位置的组合给出二进制11000001111110,结果是十进制的12414。

这可能是解释它的最简单方法,如果你想了解更多,你应该阅读按位运算符以及数字的二进制表示如何工作。

要找出数字12414具有哪个标志,可以使用&(按位AND)运算符并进行零检查。 例如:

 6 & 2 = 2 (110 has a 1 on the same position as 2, which is 010) 6 & 1 = 0 (110 does not have a 1 on the same position as 1, which is 001)