Jump to content
  • Advertisement
Sign in to follow this  
Chris27

Bitwise Operations

This topic is 4436 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been coming accross bitwise operations a lot in the introductory c++/Visual c++ book I'm reading. Are they important in game programming? I'd also like to know exactly how they work. I can see that combing differnt bits from binary results in a new value with the &/| operators, but how exactly is this used? For example at the end of the chapter the books wants me to write a program the will change the property of a variable so that can be read, write, and appended. Now if you change the bits in a variable wouldn't that change the variable itself and it takes on a new value alltogether? For instance A becomes B. A doesn't become A read only. This is all very confusing to me.

Share this post


Link to post
Share on other sites
Advertisement
There are a couple of articles on Bitwise Operations here at GameDev. The first I found in a search is:

Bitwise Operations in C

They are a fairly important thing for any programmer to know and understand and are often use to set/check flags that only need to be on or off type things.

Share this post


Link to post
Share on other sites
Consider the following


#define LVCF_FMT 0x0001
#define LVCF_WIDTH 0x0002
#define LVCF_TEXT 0x0004
#define LVCF_SUBITEM 0x0008


lvcColumnZero.mask = LVCF_FMT | LVCF_IMAGE | LVCF_TEXT ;//Format, image and text to be set



lvcColumnZero.mask can now be a single value, containing what effectively amounts to a number of bool's indicating that a particular feature is enabled/disabled.

Share this post


Link to post
Share on other sites
I'm curious isn't changing the flags also changing the character that is stored in a variable? This is what is confusing me.

Share this post


Link to post
Share on other sites
Yes, you are changing the variable value but only the bit in that field.

So consider an 8 bit ( char ). You have 8 bits or 'fields' that you can change. Each flag can be represented by one of these fields.

So for example,

ALIVE = 1
DEAD = 2
UNDEAD = 4
GHOST = 8

( note these all go up in powers of 2! )

So we can have a variable: status = 0;

status = 1 => 0000 0001 That means that the ALIVE flag is active
status = 3 => 0000 0011 That means that the ALIVE and the DEAD flag is active
status = 11 => 0000 1011 That means that GHOST/DEAD/ALIVE are all active.

So you can see that the status value can have different values but the ALIVE flag is active in all of them.



Share this post


Link to post
Share on other sites
Yes, exactly. But you need to remember that we are talking 'bit wise'. You change that specific bit, it will change the valule of the number, but the other bits remain unchanged.

lets take the following as an example.


byte var = 0x0000;

byte flag1 = 0x0001;//or binary 0000 0001
byte flag2 = 0x0002;//or binary 0000 0010
byte flag3 = 0x0004;//or binary 0000 0100
byte flag3 = 0x0008;//or binary 0000 1000

var = flag1 | flag2 | flag3 | flag4;//var now equals binary 0000 1111 because all bits in the low nibble have been set.

//what if we want to clear flag3?

var = var ^ flag3;//whatever the value of the 2^3 bit, it will be set to zero because of the exclusive or operator.


Share this post


Link to post
Share on other sites
Quote:
Original post by Chris27
I've been coming accross bitwise operations a lot in the introductory c++/Visual c++ book I'm reading. Are they important in game programming?


Seems everyone here gave you a pretty good answer about how bitwise operators work. Now, to answer the question "are they important" the answer really is "that depends". Legacy code is LOADED with bitwise functions, any straight Win32 code uses a ton of #defined bit values.

Now the gotcha, if you are writing new code, I would say HELL NO. People keep using bitwise operators because its habit. Going forward, I can only think of two reasons for you to write code that are bitwise dependant. Those are, 1: it needs to be really condenced, for example, packets of data that are going to go across the network. 2: Its in an extremely tight loop. Even excuse 2 is pretty damned wishy washy as an optimizing compiler can do pretty damned amazing things these days.

I would, 9 times out of 10, recommend the use of an enum(eration) over bit-packing, unless you have a really good reason. The maintainability/readability of your code is well worth any (possible) performance benefits.


Oh, and I guess nobody has told you the reason for using bitwise operators. Generally its to save space. For example, using a single byte, you can now represent 8 yes/no value combinations in a single value.

Share this post


Link to post
Share on other sites
........
The following post has nothing to do with Chris27's origonal question, it just reminded me of a question I had recently.
..........

Why dont you ever see something like:
#pragma pack(1)
struct _PackedChar {
const unsigned char bitOne :1;
const unsigned char bitTwo :1;
const unsigned char bitThree :1;
const unsigned char bitFour :1;
const unsigned char bitFive :1;
const unsigned char bitSix :1;
const unsigned char bitSeven :1;
const unsigned char bitEight :1;
};
#pragma pack()


I mean, it gives you the advantages of compact data storage, but without the flakeyness of using #define'd bitmasks? Plus, more strongly typed code and compile time checking.

Excuse me if its a stupid question, but I left C++ and all this stuff behind a few years back.

Share this post


Link to post
Share on other sites
That's a perfectly valid question ;)

I think most people just don't know about bitfields. But also, the "strong type checking" is often inconvenient, especially if you want to set multiple flags at once. You can't say for example "_PackedChar::bitOne | _PackedChar::bitFour". (Not to mention, naming it with an underscore followed by an uppercase letter is a bad idea; those names are reserved.)

However, you're perfectly within your rights to blast anyone who's still using *defines* for bitmasks. They should be using const ints instead, and you should tell them so.

metimmee: ^ (XOR) doesn't "clear" flags; it *toggles* them. To clear flags, AND with the complement of the flags you want to clear (&~).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!