有时我会遇到以下代码。我相信它用于将值表示为位,它们可以组合成一个数字并稍后检索。
数字34由01000000
和00000100
或2
和32
组成。我如何在Java中解决这个问题?不知何故,我必须将2与某个变量进行比较以执行X
,并将32与另一个变量进行比较以执行Y
。
以下是我的一些想法的例子。
来自DotA modding wiki的。
DOTA_ABILITY_BEHAVIOR_HIDDEN = 1 << 0, //Can be owned by a unit but can't be cast and won't show up on the HUD.
DOTA_ABILITY_BEHAVIOR_PASSIVE = 1 << 1, //Cannot be cast like above but this one shows up on the ability HUD.
DOTA_ABILITY_BEHAVIOR_NO_TARGET = 1 << 2, //Doesn't need a target to be cast, ability fires off as soon as the button is pressed.
DOTA_ABILITY_BEHAVIOR_UNIT_TARGET = 1 << 3, //Needs a target to be cast on.
DOTA_ABILITY_BEHAVIOR_POINT = 1 << 4, //Can be cast anywhere the mouse cursor is (if a unit is clicked it will just be cast where the unit was standing).
DOTA_ABILITY_BEHAVIOR_AOE = 1 << 5, //Draws a radius where the ability will have effect. Kinda like POINT but with a an area of effect display.
//...
所以这些“行为”被存储为1,2,4,8,16,32等。但是这样的整个想法似乎能够将多种类型存储到单个数字/字节中并稍后检索它们。我看到这样的用法:
DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
似乎是34
。产生34的唯一组合将是这一个DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
并且我相信只要你不使用相同的值两次,这种方式的每个组合都是唯一的。
那么如何从数字34
中检索这两个数字呢?这样的用法是否有任何限制?
答案 0 :(得分:4)
这些特殊数字称为位掩码,用于设置和读出二进制标记。
{A byte
,short
因此,int
或long
值可以容纳多个这些标志。
示例:
int flag1 = 0b0000001; // 1<<0, or 1
int flag2 = 0b0000010; // 1<<1, or 2
int flag3 = 0b0000100; // 1<<2, or 4
组合旗帜:
int combined= flag1 | flag2;
设置标志:
combined = combined | flag3;
取消设置标志:
combined = combined & ~flag;
检查是否设置了标志:
boolean set3 = (combined & flag3) !=0;
答案 1 :(得分:1)
int x = DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
if (x & DOTA_ABILITY_BEHAVIOR_AOE == DOTA_ABILITY_BEHAVIOR_AOE)
// do stuff
您可以添加由单个位表示的任意数量的值,因为数据类型可以存储。
答案 2 :(得分:1)
关于你提到如何取回用于获取的位数的部分34.我将发布一个“解决方案”,以便了解实现它的一种方法。这可能不是最好的方式。
你提到过......
DOTA_ABILITY_BEHAVIOR_HIDDEN = 1 << 0 # 0 0 0 0 0 0 0 1
DOTA_ABILITY_BEHAVIOR_PASSIVE = 1 << 1 # 0 0 0 0 0 0 1 0
DOTA_ABILITY_BEHAVIOR_NO_TARGET = 1 << 2 # 0 0 0 0 0 1 0 0
DOTA_ABILITY_BEHAVIOR_UNIT_TARGET = 1 << 3 # 0 0 0 0 1 0 0 0
DOTA_ABILITY_BEHAVIOR_POINT = 1 << 4 # 0 0 0 1 0 0 0 0
DOTA_ABILITY_BEHAVIOR_AOE = 1 << 5 # 0 0 1 0 0 0 0 0
二进制34是0 0 1 0 0 0 1 0
。
如果我们继续向左移动并检查是否设置了第0个索引处的位。
List<Integer> indx = new ArrayList<Integer>();
int count = 0;
while(n != 0) {
if(n & 0x1 == 1)
indx.add(count);
n = n >> 1;
count++;
}
对于34,indx
将包含[1,5]
。您可以使用它来重新创建用于形成它的位[DOTA_ABILITY_BEHAVIOR_PASSIVE, DOTA_ABILITY_BEHAVIOR_AOE]
。
答案 3 :(得分:-1)
由于没有人回答您的具体问题:
Decimal 34 == Hex 0022 == Binary 0000 0000 0010 0010
您的价值观
DOTA_ABILITY_BEHAVIOR_HIDDEN = 1 << 0, // 0000 0000 0000 0001
DOTA_ABILITY_BEHAVIOR_PASSIVE = 1 << 1, // 0000 0000 0000 0010
DOTA_ABILITY_BEHAVIOR_NO_TARGET = 1 << 2, // 0000 0000 0000 0100
DOTA_ABILITY_BEHAVIOR_UNIT_TARGET = 1 << 3, // 0000 0000 0000 1000
DOTA_ABILITY_BEHAVIOR_POINT = 1 << 4, // 0000 0000 0001 0000
DOTA_ABILITY_BEHAVIOR_AOE = 1 << 5, // 0000 0000 0010 0000
可以OR一起制作小数34的两个值是
DOTA_ABILITY_BEHAVIOR_PASSIVE | DOTA_ABILITY_BEHAVIOR_AOE