位掩码问题?

时间:2010-12-28 20:11:02

标签: java bitmask

我有以下内容:

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

我真的很不知道如何使用位掩码工作,如果任何人可以提供一些技巧并解释它是如何进行的,我会非常感激。

6 个答案:

答案 0 :(得分:37)

binary中的<124> 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等于向左移位3位的第一个(二进制1,仅在位位置0下降)。请注意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 

答案 1 :(得分:20)

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

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

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

TRADEABLE                1 << 1  =     2
SELLABLE                 1 << 2  =     4
STORABLE                 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
========================================
                         Total   = 12414

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

答案 2 :(得分:5)

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

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

TRADEABLE
SELLABLE
STORABLE
STORABLE_IN_WH
STORABLE_IN_LEGION_WH
BREAKABLE
BLACK_CLOUD_TRADERS
CAN_SPLIT

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

在二进制中,12414是11000001111110.二进制的LIMIT_ONE是1并且&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt ;,,因此,二进制可交换为10,依此类推,直到unk16,最终为1000000000000000.现在你使用按位OR将这些值放在一起,这基本上在每个位置放置1,其中至少有一个操作数在该位置有一个(管道运算符'|'在大多数语言中使用。)

示例:

100 | 10 = 110

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

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

要找出号码12414中的哪个标志,您可以使用&amp; (按位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)
相关问题