Archived

This topic is now archived and is closed to further replies.

elis-cool

bitwise | function parameters...

Recommended Posts

Well I took this qustion to TA like any good little boy should but then Cow_in_the_well took off on me... so Ill post it here... eliscool: so if you have like "optionA" and "optionB" and say opA is 1 and opB is 2 and so on for several options if you go optionA | optionB is would = 3 which would be optionC so you could then not use it correctly so how do u come up with the values for each? CoW_In_ThE_WeLl: what is this optionA and optionB you are talking about? variables? eliscool: yeah #defined ones CoW_In_ThE_WeLl: #define optionA 1 eliscool: yeah CoW_In_ThE_WeLl: ok eliscool: eg like with windows window styles etc... CoW_In_ThE_WeLl: and your saying you want to do #define optionC optionA | optionB ? CoW_In_ThE_WeLl: and do you mean "then not use it INcorrectly"? eliscool: no! like if opA and opB and opC were different and you want a combination of them you could not use opC as opA | opB would be == opC which is meant to be different... CoW_In_ThE_WeLl: oh i think i know what you mean eliscool: you would have to spend all day trying to come up with values that fit, it would be hell! eliscool: I will just assume your typing up an answer CoW_In_ThE_WeLl disappears from our realm... ^^ thats where he took off on me so extract what u will and try to come up with an answer for me Edit: formating... CEO Plunder Studios [edited by - elis-cool on May 6, 2002 6:51:18 AM]

Share this post


Link to post
Share on other sites
If I have understood your question right, I think the solution is to choose numbers that are a power of two:

2^0=1
2^1=2
2^2=4
2^3=8
and so on...

For example, if you add 2(Option2) and 8(Option4) it will be 10, which is 1010 in binary.

If you do 10 & 2 (To check for Option2), it will be the same as 1010 & 10 in binary and will return 1.
If you do 10 & 4 (Option3), then it will return 0 (1010 & 100=0)

Hope that solves your problem
/John

Share this post


Link to post
Share on other sites
EDIT: Hehe, simultaneous giving the same answer

erm... ok..

If I get your meaning:

Use powers of 2 for your options:

#define optionA 0x0001
#define optionB 0x0002
#define optionC 0x0004

Then you can combine them into a single int (or whatever)

optionA | optionB != optionC

ok. An alternative to using hex is to use a shift notation:

#define optionA (1<<0)
#define optionB (1<<1)
#define optionC (1<<2)

Helps?


[edited by - JuNC on May 6, 2002 6:57:29 AM]

Share this post


Link to post
Share on other sites
K thanks, it should help, havent checked yet but just to clarify:

    
#define optionA 1

#define optionB 2

#define optionC 4

#define optionD 8

#define optionE 16

#define optionF 32

#define optionG 64

#define optionH 128

#define optionI 256

#define optionJ 512


Function(optionB | optionF);

void Function(int selection)
{
switch(selection)
{
case optionA: // do stuff

case optionB: // do stuff

case optionC: // do stuff

...
case (optionA | optionB) // do combined stuff eg if optionA

// was for orange colour and optionB

// was NE direction it would do that

// I assume this is how you are

// meant to do it?

}









Edit: source formating...

CEO Plunder Studios

[edited by - elis-cool on May 6, 2002 7:07:20 AM]

Share this post


Link to post
Share on other sites
You probably shouldn''t use a switch to come up with your decisions. Instead, use if statements for each option.


  
function(int selection)
{
if(selection & optionA) //Do whatever for optionA

if(selection & optionB) //Do whatever for optionB

//Etc, do that for each option.

}

This will work if each of your options are independant, ie any combination of options are valid, and you having one option set won''t effect any other options. Doing it this way prevents you from having to figure out the hundreds of combinations associated with with 8 flags. If that''s not the case, then things get a little more complicated depending on what you need.

If optionA is red, and optionB is blue, and having both set is incorrect, then you can just check for whichever option takes precedence, and use else if to check for the second option. That way, only one option will be processed at a time.

If two flags effect one another, then check for both at once:

  
if( (selection & optionA) && (selection & optionB) )
//do whatever is needed if both options are set

else if(selection & optionA)
//do whatever is needed if only A is set

else if(selection & optionB)
//do whatever is needed if only B is set



If you have several flags that effect one another, then using switches might be the way to go after all:

  
//OptionA, optionB, and optionC all effect one another


//This strips selection of all flags except the ones we''re interested in

int bits = selection & (optionA | optionB | optionC);
switch(bits) {
case optionA | optionB | optionC: break;
case optionA | optionB: break;
//etc for all reasonable combinations

}


I think that''s basically everything. Hope it helps...

CM

Share this post


Link to post
Share on other sites
stylewise i prefer:

          
// gentity->flags

#define FL_GODMODE 0x00000010
#define FL_NOTARGET 0x00000020
#define FL_TEAMSLAVE 0x00000400 // not the first on the team

#define FL_NO_KNOCKBACK 0x00000800

#define FL_DROPPED_ITEM 0x00001000

#define FL_NO_BOTS 0x00002000 // spawn point not for bot use


#define FL_NO_HUMANS 0x00004000 // spawn point just for bots


much easier to see errors
dont ask me why they skipped 0x00000040 and 0x00000080 not my code =)


[edited by - declspec on May 6, 2002 1:04:43 PM]

[edited by - declspec on May 6, 2002 1:05:30 PM]

[edited by - declspec on May 6, 2002 1:05:56 PM]

[edited by - declspec on May 6, 2002 1:06:33 PM]

[edited by - declspec on May 6, 2002 1:07:11 PM]

Share this post


Link to post
Share on other sites
I prefer this way:

const int FLAG_1 = 1 << 0;
const int FLAG_2 = 1 << 1;
const int FLAG_3 = 1 << 2;
const int FLAG_4 = 1 << 3;
const int FLAG_5 = 1 << 4;
...
const int FLAG_32 = 1 << 31;



[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files ]

Share this post


Link to post
Share on other sites
quote:
Original post by Conner McCloud
You probably shouldn't use a switch to come up with your decisions. Instead, use if statements for each option.

function(int selection)
{
if(selection & optionA) //Do whatever for optionA
if(selection & optionB) //Do whatever for optionB
//Etc, do that for each option.
}

This will work if each of your options are independant, ie any combination of options are valid, and you having one option set won't effect any other options. Doing it this way prevents you from having to figure out the hundreds of combinations associated with with 8 flags. If that's not the case, then things get a little more complicated depending on what you need.


I dont really get what you mean here...



CEO Plunder Studios

[edited by - elis-cool on May 7, 2002 3:06:04 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Conner McCloud
You probably shouldn''t use a switch to come up with your decisions. Instead, use if statements for each option.

Switches allow you to utilize fall-through and default behavior. It can end up being less code.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ ]
[ MS RTFM [MSDN] | SGI STL Docs | Boost ]
[ Google! | Asking Smart Questions | Jargon File ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
Don''t use an & (AND) or an ^ (XOR) with a switch case though... stick with the | (OR) if you go with that approach.

Share this post


Link to post
Share on other sites
"'This will work if each of your options are independant, ie any combination of options are valid, and you having one option set won't effect any other options. Doing it this way prevents you from having to figure out the hundreds of combinations associated with with 8 flags. If that's not the case, then things get a little more complicated depending on what you need.'

I dont really get what you mean here..."

If you've got eight options that don't effect each other at all, then if statements are probably easier to work with than switch statements because you don't have to worry about combinations of options. So lets say optionA makes the sprite transparent, optionB mirrors the sprite, and optionC stretches the sprite to twice its actual size. You could do this:

      
switch(selection) {
case optionA:
//Make the sprite transparent

break;
case optionB:
//Mirror the sprite

break;
case optionC:
//Stretch the sprite

break;
case optionA | optionB:
//Make the sprite transparent

//Mirror the sprite

break;
case optionA | optionC:
//Make the sprite transperent

//Mirror the sprite

break;
case optionB | optionC:
//Mirror the sprite

//Stretch the sprite

break;
case optionA | optionB | optionC:
//Make the sprite transparent

//Mirror the sprite

//Stretch the sprite

break;
}

That's a lot of repeated code, and its really easy to forget a particual combination if you have five or six options you're trying to consider. This would be much easier:

  
if(selection & optionA)
//Make the sprite transparent

if(selection & optionB)
//Mirror the sprite

if(selection & optionC)
//Stretch the sprite


Because those three functions can be set in any combination, the if code is considerably easier than the switch code and provides the exact same functionality. If, though, optionA were to make the sprite red and optionB were to make the sprite green, it wouldn't work right because you can't have both optionA and optionB set at the same time. So any combination of options aren't valid. If optionA were to double the size of the sprite, and optionB were to change the stretch amount to triple the original size, then the if code wouldn't work either because you have to consider both optionA and optionB at the same time, they aren't independant of one another.

"Switches allow you to utilize fall-through and default behavior. It can end up being less code."

Agreed, but I haven't ever come across a situation where it was neccessary. So I didn't mention it. My main point, though, was that you shouldn't write one big switch statement with every logical combination of flags, because in almost all circumstances that'll be more code with additional room for errors. That seemed to be the direction elis-cool was going in, so I pointed out a more general method.

CM

[edited by - Conner McCloud on May 7, 2002 12:33:57 PM]

[edited by - Conner McCloud on May 7, 2002 12:34:30 PM]

Share this post


Link to post
Share on other sites