1

I was looking at an example of reading bits from a byte and the implementation looked simple and easy to understand. I was wondering if anyone has a similar example of how to insert bits into a byte or byte array, that is easier to understand and also implement like the example below.

Here is the example I found of reading bits from a byte:

    static int GetBits3(byte b, int offset, int count)
    {
           return (b >> offset) & ((1 << count) - 1);
    }

Here is what I'm trying to do. This is my current implementation, I'm just a little confused with the bit-masking/shifting, etc., so I'm trying to find out if there is an easier way to do what I'm doing

BYTE Msg[2];
Msg_Id = 3;
Msg_Event = 1;
Msg_Ready = 2;

Msg[0] = ( ( Msg_Event << 4 ) & 0xF0 ) | ( Msg_Id & 0x0F ) ;
Msg[1] = Msg_Ready  & 0x0F;     //MsgReady & Unused
Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
JB_SO
  • 471
  • 3
  • 8
  • 18
  • You problem is not clear. When you say "insert" do you mean replace existing bits or just insert in a way that other bits are shifted aside? – user88637 May 17 '10 at 14:14
  • try this - http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c – SysAdmin May 17 '10 at 14:16

2 Answers2

3

If you are using consecutive integer constant values like in the example above, you should shift the bits with these constants when putting them inside a byte. Otherwise they overlap: in your example, Msg_Id equals Msg_Event & Msg_Ready. These can be used like

Msg[0] = ( 1 << Msg_Event ) | ( 1 << Msg_Id); // sets the 2nd and 4th bits

(Note that bits within a byte are indexed from 0.) The other approach would be using powers of 2 as constant values:

Msg_Id = 4;    // equals 1 << 2
Msg_Event = 1; // equals 1 << 0
Msg_Ready = 2; // equals 1 << 1

Note that in your code above, masking with 0x0F or 0xF0 is not really needed: (Msg_Id & 0x0F) == Msg_Id and ((Msg_Event << 4) & 0xF0) == (Msg_Event << 4).

Péter Török
  • 114,404
  • 31
  • 268
  • 329
2

You could use a bit field. For instance :

struct Msg
{
   unsigned MsgEvent  : 1; // 1 bit
   unsigned MsgReady  : 1; // 1 bit
};

You could then use a union to manipulate either the bitfield or the byte, something like this :

struct MsgBitField {
   unsigned MsgEvent : 1; // 1 bit
   unsigned MsgReady : 1; // 1 bit
};

union ByteAsBitField {
   unsigned char Byte;
   MsgBitField Message;
};

int main() {
   ByteAsBitField MyByte;
   MyByte.Byte = 0;
   MyByte.Message.MsgEvent = true;
}
Jérôme
  • 26,567
  • 29
  • 98
  • 120