   Packing info into bits of a byte
  Hello,I want to minimise my bandwidth requirements by packing my client/server data into bits within bytes.eg:enum motionFlags {  MOTION_NONE= 0x0000,   // 0b00000000  MOTION_ROLLLEFT= 0x0001,   // 0b00000001  MOTION_ROLLRIGHT= 0x0002,   // 0b00000010  MOTION_PITCHUP= 0x0004,   // 0b00000100  MOTION_PITCHDOWN= 0x0008,   // 0b00001000  MOTION_MOVEFORWARD   = 0x0010,   // 0b00010000  MOTION_MOVEBACKWARD   = 0x0020    // 0b00100000};etc.....In this way, A single byte can contain various bits of info about an objects movement.I know I can test for a roll moveforward like this:if ( motionFlag && MOTION_MOVEFORWARD ) .....How do I set and clear the bits in the first place.. likethis?motionFlag |= MOTION_MOVEFORWARD;Thanks, I am confused!Simon   
  To set:motionFlag |= MOTION_MOVEFORWARD;To clear:motionFlag &= ~MOTION_MOVEFORWARD;You could also use bitfields.   ;  Hello,Let me see if I can help you out.  First, you will want to use the bits for states that can occur simultaneously.  In your example, it doesn't look like those states could occur at the same time, so it would be a waste to use separate bits.  Instead, you could use 3 bits (8 values) to cover those states.When checking a flag, make sure to use one ampersand:if( flag & FLAG_DEFINE)You have setting correct.To clear you can use something like:flag &= ~FLAG_DEFINEThe tilde inverts the flag, which clears it when you AND it.Hope that helps.-MikeEDIT : wow everyone replied around the same time :)   ;  There is two problems with:if ( motionFlag && MOTION_MOVEFORWARD )First you shoudn't use motionFlag, but an object of type motionFlag, like this:motionFlag MF;if ( MF && MOTION_MOVEFORWARD )The second problem is that && and & is two different operators, so your example is the same as saying "if motionFlag is not NULL AND MOTION_MOVEFORWARD is not NULL". You should instead use the & operator.You can set a bit like this:motionFlag MF;MF |= MOTION_ROLLLEFT;And you clear a bit like this:MF &= ~MOTION_ROLLLEFT; // ~ is the not operator;Quote:Original post by sipicklesI know I can test for a roll moveforward like this:if ( motionFlag && MOTION_MOVEFORWARD ) .....Wrong, use if ( motionFlag & MOTION_MOVEFORWARD ) .....instead (note the binary & instad of the logical &&).Quote:How do I set and clear the bits in the first place.. likethis?motionFlag |= MOTION_MOVEFORWARD;Thanks, I am confused!SimonSet a bit:motionFlag |= MOTION_MOVEFORWARD;Clear a bit:motionFlag &= ~MOTION_MOVEFORWARD;Only specify 1-bits in the enum. This avoids confusion.   ;  Thanks for making it all so clear!(A little knowledge is a dangerous thing!) :)What are the bitfields sordid mentions?   ;  A long time ago I made two functions that handled that stuff for me./*****************************************************************************  This function takes the value of unsinged char byte and sets the bit,  int bit (0-7) to bool value and returns the resulting unsigned char.*****************************************************************************/inline unsigned char STRUTILSetBit(int bit, unsigned char byte, bool value){unsigned char table[8] = {1,2,4,8,16,32,64,128};unsigned char check = table[bit]; // set check to blank byte with selected bit onif (value) // if on then...return byte | check; // turn bit onelse if (byte & check) // First, check if bit is onreturn byte^check; // if so then turn bit offreturn byte; // if not return byte since bit is already off}/*****************************************************************************  This function takes the value of unsinged char byte and returns the  true/false status of the bit int bit (0-7).*****************************************************************************/inline bool STRUTILCheckBit(int bit, unsigned char byte){unsigned char table[8] = {1,2,4,8,16,32,64,128};return (byte & table[bit])!=0;}*edit These are old and can be improved upon*[Edited by - T1Oracle on December 27, 2005 5:10:54 PM];  You can use xor to toggle a bit, for example:motionFlag ^= MOTION_MOVEFORWARD will set it, and to unset it (if it is set) you can do motionFlag ^= MOTION_MOVEFORWARD again.  Exclusive or is only true when one is true, but not both, so since both are true, it evaluates to false.  Be sure to note that it toggles, and doesnt set or clear only.   ;  Hm... as nobody mentioned it, I wonder what might be so bad about it.struct motionFlags {   unsigned char None : 1;   unsigned char RollLeft : 1;   unsigned char RollRight : 1;   ...};and they will all use one bit. Though there will always be the full number of bits for the specified type, using only 4 of them would mean 4 bits are wasted. And I have no idea how efficiently the compiler handles accesses.   ;  or you can be really cheeky and use both reprentations.... ;)enum eMotionFlags {MOTION_NONE = 0x0000, // 0b00000000MOTION_ROLLLEFT = 0x0001, // 0b00000001MOTION_ROLLRIGHT = 0x0002, // 0b00000010MOTION_PITCHUP = 0x0004, // 0b00000100MOTION_PITCHDOWN = 0x0008, // 0b00001000MOTION_MOVEFORWARD = 0x0010, // 0b00010000MOTION_MOVEBACKWARD = 0x0020 // 0b00100000};#pragma pack(push,1)struct motionFlags {  union  {    struct { unsigned char RollLeft : 1; unsigned char RollRight : 1; unsigned char PitchUp : 1; unsigned char PitchDown : 1; unsigned char MoveForward : 1; unsigned char MoveBackward : 1; unsigned char Reserved : 2;    };    unsigned char asInt;  };};#pragma pack(pop)(there is nothing bad about it AFAIK).   