Tutorial: bitwise"&" operator use, **very useful**

Posted By: Rhuarc

Tutorial: bitwise"&" operator use, **very useful** - 10/29/03 11:54

This is a method that you find used commonly in C++ (like in the 3dgs sdk for example) but is rarely used in Cscript to my knowledge. Unfortunately, nobody realizes the power that this technique can have. It is used (in a rather advanced form) in weapons.wdl. The common use for this technique is to store several flags in a single number, by assigning each flag a square number. You are likely wondering how this works, and a little about the & operator, so I'll start right into some example code:
Code:
 var flaglist;

define _flag1,2;
define _flag2,4;
define _flagA,8;
define _flagZ,16;//all flags get assigned a unique square number


This is the basic setup we work from. Now, to set the flags:
Code:
 flaglist = _flag1 + _flagA; 


Now your flaglist is equal to 10. Later in the code, we want to find out which flags were put into the original value, _flag1 and _flagA in this case. This is where some blackbox code comes into play (you could work it down as to how it works, but I will not go into the binary equivilents to square decimal numbers). How in the world are we to acheive this?? The user could have put in 2, 1, and 7, how would we know after the calculation? This is why we work only with square numbers. Is there any other combination of square numbers that would equal 10 (without using one twice)? No, there isn't! Now, you can probably now see a complex method of reasoning this out with a lengthly series of IF statements like
Code:
 if(flaglist==10) { //then we know that flag1 and flagA were activated... insert appropriate code here

}


This can be tedious and entirely unneccesary. There is a lovely operator called the bitwise-AND which works at a binary level, which I won't go into the technicalities of. The thing is this: we can now test to see if any single flag was in the original addition of flags with one simple statement:
Code:
 if( (flaglist & _flag1) != 0) 


Note that this is different than using the && operator.
I'm trying to be fairly brief, so, a final analysis can be made from this code snippet that you can play with to your hearts delight.
Code:
 define _temp_flags,skill1;

define _transparent,2;
define _flare,4;
define _bright,8;
define _passable,16;
define _shadow,32;
define _user_rotate,64;
//add whatever else you would like for user-defined flags here

function setflagsInEnt()
{
if((my._temp_flags & _transparent) != 0) { my.transparent = on; }
if((my._temp_flags & _flare) != 0) { my.flare = on; }
if((my._temp_flags & _bright) != 0) { my.bright = on; }
if((my._temp_flags & _passable) != 0) { my.passable = on; }
if((my._temp_flags & _shadow) != 0) { my.shadow = on; }
if((my._temp_flags & _user_rotate) != 0)
{
while(1)
{
my.pan += time;
wait(1);
}
}
}

action test_object
{
my._temp_flags = _transparent + _bright + _shadow + _passable +_user_rotate;
setflagsInEnt();
}



I'll make this a little more understandable next time I'm online and can add to it.

EDIT: fixed a little copy/pase error.
Posted By: GhostDude

Re: Tutorial: bitwise"&" operator use, **very useful** - 10/31/03 11:15

A very good explanation! I think this is very helpful, thank you Rhuarc!
Posted By: poke_smot

Re: Tutorial: bitwise"&" operator use, **very useful** - 11/05/03 05:23

This is a good read, please, continue...
Posted By: Rhuarc

Re: Tutorial: bitwise"&" operator use, **very useful** - 11/05/03 07:07

I'm glad it helped you out. I'll try to get the next part together, which will go into double-flags.
Posted By: Odin

Re: Tutorial: bitwise"&" operator use, **very useful** - 11/20/03 03:16

Very good explanation. This is underused by most and can be very powerful.
Posted By: Grimber

Re: Tutorial: bitwise"&" operator use, **very useful** - 11/20/03 14:25

cool, hope you continue this. & and % were always the 2 operands when i was learning C++ that i always struggled with ( and still do).

Hope you will cover them both

Posted By: Anonymous

Re: Tutorial: bitwise"&" operator use, **very useful** - 11/27/03 02:16

This is one of the most useful posts I have seen on this forum. It's basic, but could save a lot of people a lot of typing. One note, just 'cause I'm a picky math person: the "square" numbers mentioned are actually "powers of two" not squares. So for those of you wondering why 8 is on the list and 9 isn't, that's why.

Thanks for posting this, Rhuarc! You da man!
Posted By: Tobias_Runde

Re: Tutorial: bitwise"&" operator use, **very useful** - 11/27/03 07:29

Very good, but please remember that && is faster than &.
But your explanation ist very good and useful!
Posted By: FBL

Re: Tutorial: bitwise"&" operator use, **very usef - 11/27/03 09:47

I'm using & and | a lot to save variables and if-checks.

But it's also very useful for networking. If you ened to transfer controls or things like that you only need binary numbers - for checking whether a certain key is pressed or not e.g. Now you add it ll up in one variable and send it to the server. On the server you can retrieve the pressed keys by using &. This way you reduce bandwith usage.
Posted By: fastlane69

Re: Tutorial: bitwise"&" operator use, **very usef - 11/28/03 04:01

I use it for equipment storage. In my project, the players can own only one of each item type; there is no stacking; Hence, I set each item type to a power of 2 like above. I can then add these items to a single var and get a unique var:
my_equipment= 2+4+8= 14; Thus 14 is a unique number indicating that I own items 2, 4, and 8.

I can then use the "&" command to check to see if I own that item. In an of itself not too amazing, but it sure is efficient and elegant.

What I really like is that using the | command I can add the item BUT ONLY ONCE. That is to say, when I add the item to my equipment I don't ADD like this in

my_equipment+= new_item; //no no no!

No. This suffers from having to institute checks and balances such that if you select the same equipment twice, you don't continuasly add an item. By using the | command

my_equipment= my_equipment|new_item;

no matter how many times you select the same item (for example with a mouse click), you can't set the flag more than once so it automatically doesnt' overset the var.

Hence, using one skill, I can store 19 unique items. Using two skills I can store 361 items, which I find is more than enough for me. While I have no use for it, you could conceivable set three skills to equipment storage (for a total of 6859 items!!!!) and take advantage of vector fuctions to manipulate your equipment.
Posted By: Rhuarc

Re: Tutorial: bitwise"&" operator use, **very usef - 11/28/03 13:37

I'm using it for my inventory system as well. I have a (simulated) 2d array containting all my details for each inventory item, and set flags within that. I then store handles in another array for containers to keep track of where my inventory items are.
Posted By: fastlane69

Re: Tutorial: bitwise"&" operator use, **very usef - 12/01/03 11:58

1) Since 3DGS vars have 3 decimal places, this is 6 bits and theoretcally, 6 more items. How, if at all, could we use the bitwise commands to take advantage of decimals places?

2) Along the same vein, the sign of a var would be an extra bit. Could I do the following check:

if(bit_info&-1)
{
do_something();
}

if(bit_info&1)
{
do_something_else();
}


Posted By: fastlane69

Re: Tutorial: bitwise"&" operator use, **very usef - 12/01/03 17:30

answered my second question: it seems that bitwise operations aren't sensative to the +/- sign.

I suspect this means they aren't wise to the decimals.
Posted By: FBL

Re: Tutorial: bitwise"&" operator use, **very usef - 12/02/03 08:30

I haven't tried, but normally it's open to interpretation, whether a number is positive or not.

A5 uses a fixpoint format, I think it was 22.10

This means we have a size of 4 byte, this is 32 bits.
The last 10 (1024 combinations, makes 3 decimal places) bits are taken for the positions after the decimal point, the remaining 22 bits are used for the positions before the decimal point.
With this format, we can store numbers, but there is no informations about the sign yet.
To get negatvie and positive numbers, the highest bit is used. A 1 means negatvie number, a 0 means negative number.

You might think we lose a lot of place with this as we only have 21 (2097152 combinations) instead of 22 (4194304) bits. That is not true. In fact we only moved the area where we can store numbers. We can't use that high positive nubmers anymore, therefore we can store negative numbers. It's all a question of interpretation.

(The fixpoint format of A5/6 might differ from 22.10, I don't know it out of my mind right now. The idea behind it is the same, it only changes the maximum number sizes/precision before and behind the decimal point. Maybe Conitec also uses some of the leading bits as variable flags like the info flag, I guess you will have to ask Conitec about that for more details)
Posted By: fastlane69

Re: Tutorial: bitwise"&" operator use, **very usef - 12/02/03 15:13

Thanks for the clarification Firo.

So far, I can use the +/- info by doing two checks: first if my value is > or < 0 (ie plus or minus), and then I do a bit check. In my application, this is the way I control whetehr an item is being put on or off: if the bit is +, then that item is added; if -, then subtracted.

So far, It seems I can't do a direct bitwise check for -1. I'll experiement a little with the bits and see what kind of control I can wrangle out of them. Want to see if I can use the decimal places in the same way as the main places.
Posted By: FBL

Re: Tutorial: bitwise"&" operator use, **very usef - 12/02/03 21:38

Sorry I made a mistake above. most significant bit=0 means positive number, of course.
Posted By: indiGLOW

Re: Tutorial: bitwise"&" operator use, **very useful** - 12/19/03 03:43

Give that man a round of applause....
The implications of this if used properly is huge.... I gave you 5 stars and I would have given more. THIS IS the most informative post @ this forum I have read!

It has so many uses, and the bandwidth saved? well it could make multiplay very effecient....

Thanks for making the obvious so clear.
Posted By: Rhuarc

Re: Tutorial: bitwise"&" operator use, **very useful** - 12/23/03 02:04

Hehe, thanks man.
I actually am looking at ways to compress the number (might have to go to a dll) into a smaller variable type for multiplayer use. Also, there are methods to store *multiple* strings of flags within it by adding other non-square numbers, but I'm still trying to sort that one out in my head. Thats when you get into prime numbers and such. (eyes start rolling in different directions....) I hope I'm on the right track .

-Rhuarc
Posted By: indiGLOW

Re: Tutorial: bitwise"&" operator use, **very usef - 12/17/05 17:35

Wow, almost 2 years ago I read this post! Here I am all that time later returning to it. Fantastic!

Everyone should read this, at least twice! lol
Posted By: Nadester

Re: Tutorial: bitwise"&" operator use, **very usef - 12/19/05 02:52

I'd yell at you for reviving an old topic, but I'm not going to because this is a very important subject

But so much more could be said about bitwise operations. A better way to set and turn off specific bits than what rhuarc said is like below:

// maybe give these names for when you set skill flags
#define bit0, 0x1;
#define bit1, 0x2;
#define bit2, 0x4;
#define bit3, 0x8;
#define bit4, 0x10;
#define bit5, 0x20;
#define bit6, 0x40;
#define bit7, 0x80;

var flags;

// turn a bit on...
function turnbiton()
{
flags|=BIT0;
flags|=(BIT1|BIT2|BIT3|BIT4);
}

// turn bit off
function turnbiton()
{
flags&=^BIT5;
flags&=^(BIT1|BIT2|BIT3|BIT4);
}
Posted By: indiGLOW

Re: Tutorial: bitwise"&" operator use, **very usef - 12/20/05 00:22

Yeah I would smack my self in the face for reviving an old topic, but I actually was in need of this, had forgotten how to implement it, and there it was on my favourites list.

I don't think this ever was taken as far as it could be, using the square numbers meant the definition text was growing at an incredible length lol

I am gonna have to get up early and chew the fat on your take on bitwise implementation! Thanks for not chewing my face off for dragging the post up again
Posted By: indiGLOW

Re: Tutorial: bitwise"&" operator use, **very usef - 12/21/05 12:46

I just been talking to someone about using this method for node based path finding?

Im thinking that, each node has the skills set to the appropriate square number, incremented for ALL nodes, then a route through the nodes, could be stored like this...but could it also help work it out? I mean if you know the target node is 64, can you work out the route? Just thinking out loud
Posted By: VeT

Re: Tutorial: bitwise"&" operator use, **very usef - 07/22/09 11:53

Great thread, this mustn't be lost.
Posted By: Germanunkol

Re: Tutorial: bitwise"&" operator use, **very usef - 07/22/09 13:54

wow, how long have you been searching to find this old thread? 2005 smile

I agree though, very important stuff here.
Just see the potential for mutliplayer games! If I have four guns and want to tell another user which of these was fired, with this I only need to send one value instead of 4...


Just a question though: has this changed now that we use LiteC and not Cscript?
How would you code the same thing with liteC?

Posted By: Joozey

Re: Tutorial: bitwise"&" operator use, **very usef - 07/22/09 14:40

#define setBit( x, n ) ( x |= (1<<n) ) //puts bit n in x on true (n=3, 10110 | 01000 = 11110 )
#define resetBit( x, n ) ( x ^= (1<<n) ) //puts bit n in x on false (n=3, 10110 ^ 00100 = 10010)

#define getBit( x, n ) ( x & (1<<n) ) //returns true when bit n in x is set (n=3, 10110 & 00100 = 00100 so TRUE ) (n=4, 10110 & 01000 = 00000 so FALSE)

int weaponsFired = 0;
setBit( weaponsFired, 3 ); //player 3 has fired (0000 | 0100 = 0100)
setBit( weaponsFired, 1 ); //player 1 has fired (0100 | 0001 = 0101)

if( getBit( weaponsFired, 3 ) ) { die(); } //we die due to player 3 (0101 & 0100 = TRUE)

resetBit( weaponsFired, 3 ); //player 3 stopped shooting, player 1 not (0101 ^ 0100 = 0001)
Posted By: Xarthor

Re: Tutorial: bitwise"&" operator use, **very usef - 07/22/09 15:49

Interesting Joozey but one small mistake in your first example of the getBit macro:
n=3, 10110 & 00100 = 00100 so TRUE

either you meant n=2 or you need to add a zero at the end ;-)
Posted By: Germanunkol

Re: Tutorial: bitwise"&" operator use, **very usef - 07/22/09 16:17

great, thanks! smile
Posted By: Joozey

Re: Tutorial: bitwise"&" operator use, **very usef - 07/22/09 22:09

I did made a minor mistake by not stating that the FALSE example is n=4. ((1<<4) makes 1000, (1<<3) makes 0100) From what I understand from your post you read the bits from left to right. But bits are to be read from right to left, and the remaining 0's are actually redundant.

0001 = 1 = 1
0010 = 10 = 2
0011 = 11 = 3
0100 = 100 = 4
0101 = 101 = 5
...
Posted By: Xarthor

Re: Tutorial: bitwise"&" operator use, **very usef - 07/23/09 06:41

no I also read from right to left but I guess I had a mistake in my thoughts somewhere else.
I assumed that the shifting starts with zero, so (1<<0) would make 0001 and (1<<3) makes 1000
But I guess thats wrong here.
Sorry for disturbing wink
© 2024 lite-C Forums