Page 1 of 1

binary in const

Posted: Sat Sep 30, 2006 6:48 am
by innominabile
Can I use:

const var := 0b0001111001010;

in const declatation?

Posted: Sat Sep 30, 2006 10:24 am
by MuadDib
Yes, and at the same time, no.

You wouldn't use the direct Binary representation, but rather it's dec or hex value. If you look at the stat lock hook for 097 Distro, it will show you what I mean. Stat locks are Binary handled, and it is used with them there thanks to help from folko.

Posted: Sat Sep 30, 2006 11:21 am
by innominabile
I am written 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
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]

Posted: Sat Sep 30, 2006 4:09 pm
by 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:

Code: Select all

function GetProtectionAmount(object, protection_mask)
  var protections := Cint(GetObjProperty(object, "Protections"));
  if (!((protections & protection_mask)==protection_mask))
    return 0;
  else
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.

Posted: Sat Sep 30, 2006 4:37 pm
by Marilla
Some examples, to help the binary impaired! :twisted:

Let's take two numbers:

Code: Select all

var i := 6;
var e := 8;
Represented as binary, these numbers would be:

Code: Select all

var i := 0110;
var e := 0001;
Let's say I do this, now:

Code: Select all

var f := (i & e);
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:

Code: Select all

var x := 2;   // x := 0100;
var g := (x & i);
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:

Code: Select all

var y := 7;  // y := 1110;
var z := (y & i);
Here we have 1110 AND 0110. This has bits 2 and 3 on, meaning z will equal 6.

Finally, let's do this:

Code: Select all

var a := 12;  //a := 0011;
var b := (a & i);
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:

Code: Select all

var p_fire := 1; //1000;
var p_water := 2; //0100;
var p_energy := 4; //0010;
var p_magic := 8; //0001;
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:

Code: Select all

var my_prots := p_fire + p_water;  //Not proper!
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:

Code: Select all

var my_prots := (p_fire | p_water);
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:

Code: Select all

  my_prots :=  my_prots + p_fire;
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:

Code: Select all

  my_prots := (my_prots | p_fire);
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;

Code: Select all

function HasProtection(protection)
 return (my_prots & protection) == protection);
endfunction
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:

Code: Select all

var p_magical_fire := p_fire | p_magic; //needs BOTH fire and magic. Note the |, and not +
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!

Posted: Sat Sep 30, 2006 4:53 pm
by MuadDib
Mar..... Why not just write an overall, general, "Introduction to BITS and Escript" guide, and post it in the POL Guides section? I say this, because as much as I would love to get one done myself, I simply don't have the time right now. Mind doing that? :D

Posted: Sat Sep 30, 2006 9:24 pm
by Marilla
I'll be happy to make an attempt, sure. By 'attempt', I mean who knows if I'll say everything that needs to be said, while NOT saying things that don't!

:P

Posted: Sat Sep 30, 2006 10:24 pm
by Austin
Your attempt should also include ^ XOR and >> as well as <<
POL does not support >>> because gluttony is a sin!

Posted: Sun Oct 01, 2006 12:20 am
by 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