如何从数字中检索位
How to retrieve bits from number
有时我会遇到下面的代码。我相信它用于将值表示为位,它们可以组合成一个数字并在以后检索。
数字34由01000000
和00000100
或2
和32
组成。我如何在 Java 中解决这个问题?不知何故,我必须将 2 与某个变量进行比较以执行 X
并将 32 与另一个变量进行比较以执行 Y
.
以下是我的一些想法的例子。
来自 DotA 模组维基。
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.
//...
所以这些 "behaviors" 被存储为 1、2、4、8、16、32 等。但是整个想法似乎能够将多种类型存储到一个 number/bytes 并稍后检索这些。我看到这样的用法:
DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
这似乎是 34
。唯一会产生 34 的组合是这个 DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
,我相信只要您不两次使用相同的值,以这种方式进行的每个组合都是唯一的。
那么如何从号码34
中取出这两个号码呢?还有这样的用法有什么限制吗?
int x = DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
if (x & DOTA_ABILITY_BEHAVIOR_AOE == DOTA_ABILITY_BEHAVIOR_AOE)
// do stuff
您可以添加与数据类型可以存储的一样多的单个位表示的值。
那些特殊的数字叫做位掩码,用来设置和读出二进制标志。
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;
由于没有人回答您的具体问题:
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
可以通过“或”运算得到十进制数 34 的两个值是
DOTA_ABILITY_BEHAVIOR_PASSIVE | DOTA_ABILITY_BEHAVIOR_AOE
关于您提到的如何取回用于获取 34 的位的部分。我将 post 和 'solution' 给出一种实现它的方法。这可能不是最好的方法。
您提到过...
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]
。
有时我会遇到下面的代码。我相信它用于将值表示为位,它们可以组合成一个数字并在以后检索。
数字34由01000000
和00000100
或2
和32
组成。我如何在 Java 中解决这个问题?不知何故,我必须将 2 与某个变量进行比较以执行 X
并将 32 与另一个变量进行比较以执行 Y
.
以下是我的一些想法的例子。
来自 DotA 模组维基。
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.
//...
所以这些 "behaviors" 被存储为 1、2、4、8、16、32 等。但是整个想法似乎能够将多种类型存储到一个 number/bytes 并稍后检索这些。我看到这样的用法:
DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
这似乎是 34
。唯一会产生 34 的组合是这个 DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
,我相信只要您不两次使用相同的值,以这种方式进行的每个组合都是唯一的。
那么如何从号码34
中取出这两个号码呢?还有这样的用法有什么限制吗?
int x = DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
if (x & DOTA_ABILITY_BEHAVIOR_AOE == DOTA_ABILITY_BEHAVIOR_AOE)
// do stuff
您可以添加与数据类型可以存储的一样多的单个位表示的值。
那些特殊的数字叫做位掩码,用来设置和读出二进制标志。
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;
由于没有人回答您的具体问题:
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
可以通过“或”运算得到十进制数 34 的两个值是
DOTA_ABILITY_BEHAVIOR_PASSIVE | DOTA_ABILITY_BEHAVIOR_AOE
关于您提到的如何取回用于获取 34 的位的部分。我将 post 和 'solution' 给出一种实现它的方法。这可能不是最好的方法。
您提到过...
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]
。