如何从数字

时间:2016-03-21 07:26:17

标签: java bit bit-shift

有时我会遇到以下代码。我相信它用于将值表示为位,它们可以组合成一个数字并稍后检索。

数字34由0100000000000100232组成。我如何在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中检索这两个数字呢?这样的用法是否有任何限制?

4 个答案:

答案 0 :(得分:4)

这些特殊数字称为位掩码,用于设置和读出二进制标记
{A byteshort因此,intlong值可以容纳多个这些标志。

示例:

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