我有以下内容:
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
我真的很不知道如何使用位掩码工作,如果任何人可以提供一些技巧并解释它是如何进行的,我会非常感激。
答案 0 :(得分:37)
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
相同。因此,如果您愿意,可以通过简单的添加来考虑它。
二进制数12414
为11000001111110
,因此它是以下标志的总和(或按位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 << b
将a
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位的组合。有些数字只有一位。
答案 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)