Reputation: 8584
Sometimes I come across the below code. I believe it is used to represent values as bits and they can be combined into a single number and retrieved later.
The number 34 consists of 01000000
and 00000100
or 2
and 32
. How do I work this out in Java? Somehow I have to compare 2 to some variable to do X
and 32 tot another variable to do Y
.
The following is a example with some of my thoughts.
from the 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.
//...
So these "behaviors" get stored as 1, 2, 4, 8, 16, 32, etc. But the whole idea of this seems to be able to store multiple types into a single number/bytes and retrieve these later. I see usages like this:
DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
Which seems to be 34
. The only combination that would yield 34 would be this one DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
and I believe that every combination made this way would be unique as long as you don't use the same value twice.
So how do I retrieve these two numbers from the number 34
? And are there any limitations in the usage like this?
Upvotes: 3
Views: 612
Reputation: 5403
About the part where you mentioned how to get back the bits used to obtain 34. I will post a 'solution' to give an idea about one way to achieve it. It is probably not the best way.
You have mentioned...
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
And 34 in binary is 0 0 1 0 0 0 1 0
.
If we keep shifting left and check to see if the bit at the 0th index is set.
List<Integer> indx = new ArrayList<Integer>();
int count = 0;
while(n != 0) {
if(n & 0x1 == 1)
indx.add(count);
n = n >> 1;
count++;
}
For 34, indx
will contain [1,5]
. You can use this to recreate which bits were used to form it [DOTA_ABILITY_BEHAVIOR_PASSIVE, DOTA_ABILITY_BEHAVIOR_AOE]
.
Upvotes: 1
Reputation: 86754
Since nobody has answered your specific question:
Decimal 34 == Hex 0022 == Binary 0000 0000 0010 0010
Your values are
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
The two values that can be OR'ed together to make decimal 34 are
DOTA_ABILITY_BEHAVIOR_PASSIVE | DOTA_ABILITY_BEHAVIOR_AOE
Upvotes: -1
Reputation: 15706
Those special numbers are called bit masks, used to set and read out binary flags.
A byte
, short
, int
or long
value can thus hold multiple of those flags.
Example:
int flag1 = 0b0000001; // 1<<0, or 1
int flag2 = 0b0000010; // 1<<1, or 2
int flag3 = 0b0000100; // 1<<2, or 4
To combine flags:
int combined= flag1 | flag2;
To set a flag:
combined = combined | flag3;
To unset a flag:
combined = combined & ~flag;
To check if a flag is set:
boolean set3 = (combined & flag3) !=0;
Upvotes: 4
Reputation: 5109
int x = DOTA_ABILITY_BEHAVIOR_AOE | DOTA_ABILITY_BEHAVIOR_PASSIVE
if (x & DOTA_ABILITY_BEHAVIOR_AOE == DOTA_ABILITY_BEHAVIOR_AOE)
// do stuff
You can add as many values represented by a single bit as the data type can store.
Upvotes: 1