23

我有以下内容:

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

我对位掩码的工作原理一无所知,如果有人可以提供一些提示并解释它是如何达到这个数字的,我将非常感激。

4

6 回答 6

38

二进制的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 
于 2010-12-28T20:25:15.407 回答
21

该表达式(1 << n)等价于 2 的 n 次幂。

当你写的时候,只要和不同(1 << n) | (1 << m),这是相同的。因此,如果您愿意,可以将其视为简单的添加。(1 << n) + (1 << m)nm

12414二进制中的数字11000001111110是以下标志的总和(或按位或):

可交易 1 << 1 = 2
可售 1 << 2 = 4
可储存 1 << 3 = 8
STORABLE_IN_WH 1 << 4 = 16
STORABLE_IN_LEGION_WH 1 << 5 = 32
易碎 1 << 6 = 64
黑云交易者 1 << 12 = 4096
CAN_SPLIT 1 << 13 = 8192
=========================================
                         总计 = 12414

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

于 2010-12-28T20:13:28.303 回答
5

a << ba b值中的位向左移动,用零填充右侧的新位。1 << n等于一个只有第nth 位(从右边开始计数)集合的整数,相当于 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
于 2010-12-28T20:16:01.790 回答
0

我的猜测是您取一些数字,例如您的示例 12414,并找出其中包含哪些属性。

例如,因为 12414 是二进制的 11000001111110,所以它所附加的任何东西都是可交易的,因为将这个数字与掩码进行与运算将在第二位得到 1。

于 2010-12-28T20:18:12.437 回答
0

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

例子:

100 | 10 = 110

因此,要达到 12414,您需要对以下变量进行按位或运算:unk16、unk15、tradeable、sellable、storeable、storeable in wh、storeable in legion wh 和 breakable。每个变量中不同位置的组合为您提供二进制 11000001111110,结果是十进制的 12414。

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

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

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)
于 2010-12-28T20:18:23.447 回答
0

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

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

http://en.wikipedia.org/wiki/Mask_ (计算)

于 2010-12-28T20:15:08.647 回答