binary in const
-
innominabile
- Adept Poster
- Posts: 85
- Joined: Wed Aug 30, 2006 5:24 pm
binary in const
Can I use:
const var := 0b0001111001010;
in const declatation?
const var := 0b0001111001010;
in const declatation?
-
innominabile
- Adept Poster
- Posts: 85
- Joined: Wed Aug 30, 2006 5:24 pm
I am written code:
I know I can check multiple but with a simplier:
but really I need scan bits.
Someone know a fastest mode to loop ex bits?
I think that a loop and Pow() is a very rendutttant code
(([/code]
Code: Select all
function GetProtectionAmount(object, protection_mask)
var protections := Cint(GetObjProperty(object, "Protections"));
var i, single_bit_mask;
for (i := 1; i <= 32; i := i + 1)
single_bit_mask := Pow(2, i); //Pow(2, i); // returns x ^ y
if (protection_mask & single_bit_mask)
//ok
I know I can check multiple but with a simplier:
Code: Select all
function GetProtectionAmount(object, protection_mask)
var protections := Cint(GetObjProperty(object, "Protections"));
if (!(protections & protection_mask)) // se protezione non attiva sull'oggetto
return 0;
else
Someone know a fastest mode to loop ex bits?
I think that a loop and Pow() is a very rendutttant code
-
Marilla
Ok, I'm not 100% sure what you are trying to do here, but maybe I can help anyway!
You do not need your looping code to check for a single bit. Your code should simply be the following:
Notice that I'm not testing for true/false here; I'm testing for equality with protection_mask. And yes... protection mask needs to appear TWICE in that evaluation.
The reason is this: When you do (protections & protection_mask), the return value from that calculation is a number that has the bits turned on where BOTH values also have that bit. This is the meaning of 'AND' (&); If both operands have a value, then that value is in the result. If only one of the operands have it, or neither have it, then it is not in the result.
So, if your 'protections' value includes the value from protection_mask, AND assuming protection_mask ONLY has one bit on, the result from that will be protection_mask itself.
As long as the value you are testing for will only have the exact bits on that you need, the above code will work. You could also set protection_mask to MULTIPLE bits, if you wanted a certain thing to only be protected against if they have multiple protections, but not just one or the other (say, they need Fire and Energy protection to be protected against one spell).
Again; as long as protections has All the bits that you are looking for in protection_mask, the result will be equal to protection_mask. For what you are doing, this is the exact test you need to do.
You do not need your looping code to check for a single bit. Your code should simply be the following:
Code: Select all
function GetProtectionAmount(object, protection_mask)
var protections := Cint(GetObjProperty(object, "Protections"));
if (!((protections & protection_mask)==protection_mask))
return 0;
else
The reason is this: When you do (protections & protection_mask), the return value from that calculation is a number that has the bits turned on where BOTH values also have that bit. This is the meaning of 'AND' (&); If both operands have a value, then that value is in the result. If only one of the operands have it, or neither have it, then it is not in the result.
So, if your 'protections' value includes the value from protection_mask, AND assuming protection_mask ONLY has one bit on, the result from that will be protection_mask itself.
As long as the value you are testing for will only have the exact bits on that you need, the above code will work. You could also set protection_mask to MULTIPLE bits, if you wanted a certain thing to only be protected against if they have multiple protections, but not just one or the other (say, they need Fire and Energy protection to be protected against one spell).
Again; as long as protections has All the bits that you are looking for in protection_mask, the result will be equal to protection_mask. For what you are doing, this is the exact test you need to do.
-
Marilla
Some examples, to help the binary impaired!
Let's take two numbers:
Represented as binary, these numbers would be:
Let's say I do this, now:
Remember: (x & y) returns a value where the bit values that are 'on' in BOTH variables are on, but otherwise, are off. Look at the bit values for i and e, and you'll see that they do not share ANY bit values. So, f will equal 0 here.
Let's say I do this, then:
With the binary representation of 2 being 0100, and the binary of i being 0110, we can look, and see that the 2nd bit will be returned in the value, and only that bit (since it's the only one that both have.) Therefore, g will equal 2.
Now, let's try this:
Here we have 1110 AND 0110. This has bits 2 and 3 on, meaning z will equal 6.
Finally, let's do this:
Here, we have i as 0110. a is 0011. If you look at this, only bit 3 is on on both. Meaning b will equal 4.
Of course, all of the above would not generally be of much use for when testing bit-coded values. You are usually testing for the presence of a single value. But the info above should make it easy to figure out how to do so, to come to the same conclusion I did in my post above.
Let's say we have this:
Now, a quick primer on 'OR' and how you use it to 'add' bit fields;
Let's say you want to give me protection from fire and water. You could do it like this:
That will happen to work in this case, but it is NOT how you are supposed to work with bit-coded values.
It works in this case because p_fire and p_water both only have a single bit set, meaning adding the numbers together will give you a number that has both their bits set. fire (1) plus water(2) = 3, which is 1100, which is correct, in this case. But...
The better way to combine bit-coded values is to OR them together:
OR gives you a value that looks at both numbers, and sets the return value's bits whereever EITHER value has it on, or if both do. So 1 OR 2 (1000 OR 0100) will happen also to be 3 (1100).
However, imagine you wanted to take someone's existing protections and 'add' a new protection to them; Say, we want to add 'fire' protection to whatever you might have now.
Doing this with mathematical addition can cause trouble:
What if I already HAD fire protection? The result would be, I no longer have fire protection, and have WATER protection instead! Not good! To fix this, I would have to first test for fire protection before 'adding' it in. But why do that, when I can simply do this:
This will have the result that no matter whether I have fire protection or not now, I will have it afterward. Let's say I have fire and water now: (1100). So, if I do (1100 OR 1000), the result is 1100. Say I have water and magic now (0101). If I do (0101 OR 1000) the result is (1101), which is correct; Fire, water and magic. OR turns on any bits that are on in either of the values, or both. Addition, on the other hand, is not what we want, just to be safe.
Now, then, testing for these values is easy;
If you AND a bit-coded value against the bit-coded value you are testing for, your result will be the value you are testing for, if those bits exist. Otherwise, it will be something different.
Say I currently have fire and water protection (1100). Say I call HasProtection(p_water)
(1100 & 0100) == 0100
So yes; that will work.
Say I call HasProtection(p_magic)
(1100 & 0001) == 0
So no, that will fail.
I could even do this:
If I then call HasProtection(p_magical_fire) I will get false, because I only have fire and water... not magic:
(1100 & 1001) == 1000;
The result is only the first bit on; for fire, because that's all I have that's also in the test. So I will fail that protection test. The code above WILL check that properly; It will be looking for the return value to equal the protection bit mask, which is 1001, but the result was 1000. So that's false.
Hope that helps some!
Let's take two numbers:
Code: Select all
var i := 6;
var e := 8;
Code: Select all
var i := 0110;
var e := 0001;
Code: Select all
var f := (i & e);
Let's say I do this, then:
Code: Select all
var x := 2; // x := 0100;
var g := (x & i);
Now, let's try this:
Code: Select all
var y := 7; // y := 1110;
var z := (y & i);
Finally, let's do this:
Code: Select all
var a := 12; //a := 0011;
var b := (a & i);
Of course, all of the above would not generally be of much use for when testing bit-coded values. You are usually testing for the presence of a single value. But the info above should make it easy to figure out how to do so, to come to the same conclusion I did in my post above.
Let's say we have this:
Code: Select all
var p_fire := 1; //1000;
var p_water := 2; //0100;
var p_energy := 4; //0010;
var p_magic := 8; //0001;
Let's say you want to give me protection from fire and water. You could do it like this:
Code: Select all
var my_prots := p_fire + p_water; //Not proper!
It works in this case because p_fire and p_water both only have a single bit set, meaning adding the numbers together will give you a number that has both their bits set. fire (1) plus water(2) = 3, which is 1100, which is correct, in this case. But...
The better way to combine bit-coded values is to OR them together:
Code: Select all
var my_prots := (p_fire | p_water);
However, imagine you wanted to take someone's existing protections and 'add' a new protection to them; Say, we want to add 'fire' protection to whatever you might have now.
Doing this with mathematical addition can cause trouble:
Code: Select all
my_prots := my_prots + p_fire;
Code: Select all
my_prots := (my_prots | p_fire);
Now, then, testing for these values is easy;
Code: Select all
function HasProtection(protection)
return (my_prots & protection) == protection);
endfunction
Say I currently have fire and water protection (1100). Say I call HasProtection(p_water)
(1100 & 0100) == 0100
So yes; that will work.
Say I call HasProtection(p_magic)
(1100 & 0001) == 0
So no, that will fail.
I could even do this:
Code: Select all
var p_magical_fire := p_fire | p_magic; //needs BOTH fire and magic. Note the |, and not +
(1100 & 1001) == 1000;
The result is only the first bit on; for fire, because that's all I have that's also in the test. So I will fail that protection test. The code above WILL check that properly; It will be looking for the return value to equal the protection bit mask, which is 1001, but the result was 1000. So that's false.
Hope that helps some!
-
Marilla
-
Marilla
Someone's welcome to add a post about the bit-shifting operators, if they like. As it is, I think my result is too long!
http://forums.polserver.com/viewtopic.php?p=4747
http://forums.polserver.com/viewtopic.php?p=4747