Main Site Documentation

Bits and Bytes again


#1

Guys,

Sorry if this question may sound stupid, but i must have one of those brain-strike moments ???

I receive a packet that contains several bytes. The 1st byte contains several info:
bit1: CTL
bit2: DST
bit3: ACK
bit4-8: ID

For example I receive 33 which is 0010 0001

Visually i can tell that this byte has ACK set to 1 and ID is 1.

How can I do this code wise?

Thanks in advance


#2

Hello,

what about an enum and bitwise operators ?


[Flags]
public enum Packet : short
      {
            Ctl = 0x00,
            Dst = 0x01,
            Ack = 0x02
        }

public void Test()
        {
            int Val = 33;
            if ((Packet)Val & Packet.Ack == Packet.Ack) { Debug.Print("Ack found");}
            Debug.Print ("ID = " + ((Val & 0xF0)>>4).ToString());
        }


#3

Hi Eric,

normally, bits are counted beginning with bit0. So in your case, it would mean:
bit0: CTL
bit1: DST
bit2: ACK
bit3-7: ID

Furthermore, binary notation is commonly as follows (for 33 in your case):
bit#: 7 6 5 4 3 2 1 0
bits set: 0 0 1 0 0 0 0 1

So, bits 0 and 5 are set. The decimal value of each bit is calculated by 2^bit#, in your case 2^5 + 2^0 = 33.
CTL is set to 1 and ID is 4.

Try this:

bool CTL = false;
byte Value = 33;
byte ID = 0;
CTL = Convert.ToBoolean(Value & 1);
ID = Value >> 3;

Regards
Daniel


#4

Thanks guys for the replies.

Ok, i have to learn that bit position is alway? in reverse order.

so it becomes:
bit7: CTL
bit6: DST
bit5: ACK
bit0-4: ID

Bit desc: C D A I I I I I
Bit position: 7 6 5 4 3 2 1 0
Bit Set: 0 0 1 0 0 0 0 1

In this case the ack bit has been set and the id = 00001

Hm, let me ask you this, do you know any good understandable tutorial regarding this? (bit manipulation, extraction, conversion, whatever it is called).

Eric


#5

Yet another way to do it…


	[Flags]
	enum Bits 
	{
		ACK = 0x20,
		DST = 0x40,
		CTL = 0x80,

		ACK_MASK = 0x1F,
	}
.
.
.
			byte val = 33;

			Bits bits = (Bits)val;

			bool isAck = (bits & Bits.ACK) != 0;
			bool isCtl = (bits & Bits.CTL) != 0;
			bool isDst = (bits & Bits.DST) != 0;

			int ack = (int)(bits & Bits.ACK_MASK);

			// clear ack bit
			bits &= ~Bits.ACK;

			// set ctl bit
			bits |= Bits.CTL;


#6

I played around and came up with the following:


    byte hdr = 33;

    bool CTL = ((hdr >> 5) & 0x04) != 0;
    bool DST = ((hdr >> 5) & 0x02) != 0;
    bool ACK = ((hdr >> 5) & 0x01) != 0;

How do I extract the ID in this case (bits 0 to 4) ?


#7
hdr & 0x0F;

:wink:


#8

Thanks Bec, but it should have been 0x1F i guess (5 bits), right?


#9

Of course, you’re right !

I see 4bits (8 / 2) far more often than 5, hence my quick (and bad) answer :wink:

As a programmer, you may know that there are some “reflex numbers” like this one which comes to mind almost immediately as soon as you speak of bytes and bits operations. No need to think, they come faster than anything else, even when not appropriate like here ::slight_smile: