Home > front end >  Coding in Bits. or Structuring a Byte into several different values with respect to corresponding bi
Coding in Bits. or Structuring a Byte into several different values with respect to corresponding bi

Time:10-13

I would like to have single byte with multiple funtions.

Let me explain first. Please before down voting my question, let me know what knowledge I am lacking or lagging.

I would like to split a Byte into 5 parts; that is first half byte or first four bits, with 0-15 different values.

Then the last half of the byte or last 4 bits must be separated, each bit (that is 5th, 6th, 7th, or 8th_bit) must have value of 0 or 1.

For example: if I pass value something like this "0b 1111 1 1 1 1". It should configure to the funtion which is there in value 15 of first 4 bits(0-15) and the 5th_bit(0-1) must be set(1) or clear(0) to do certain funtion and 6th, 7th, and 8th_bit must also do similar thing like 5th bit

May be if you look into the image you might get what I am trying to say. Please click the link to see the image. I am not sure about title, I think the title fits my question. I would like to achieve this in C . How to achieve this? How to do this? any examples?

CodePudding user response:

You need to learn a littel bit about boolean algebra. Most important are AND, OR and NOT operations. You can build anything with these 3 operations. There are other Operations which can also be used to come to any desired outcome, like NAND and NOR, and more. But anyway.

C has bitwise operators for AND & or OR | or NOT~. Please do not mix up with boolean logical operators &&. || and ! that work on boolean expressions.

Let us look like that bitweise operators behave. In the following example we are always talking about one sinegle bit:

AND  Result      Or   Result     NOT  Result
a b    y         a b     y       a       y
---------        ----------      ---------- 
0 0    0         0 0     0       0       1 
0 1    0         0 1     1       1       0
1 0    0         1 0     1
1 1    1         1 1     1

No we need to understand, how we can set a bit and clear a bit. From the above table you can see that

  • Something AND 0 --> is always 0. So, we can clear a bit with AND 0
  • Something OR 1 --> is always 1. So, we can set a bit with OR 1
  • Something AND 1 --> is always "Something". So, AND with 1 is a neutral operation
  • Something OR 0 --> is always "Something". So, OR with 0 is a neutral operation

OK. Now we know how to set a bit or how to clear a bit. We can also do multiple bit sets or bit clearences. So, if we want to set the uppermost 4 bits in a byte, we can write

byte = byte | 0b11110000. 

That will set the upper most 4 bits and not change the 4 lower most bits.

If we want to delete/reset/set-to-0 the bit number 0 and 1, then we can write:

byte = byte & 0b11111100. 

If we want to know the value of several bits, we can "mask" them. We can create a binary value, with bits set on positions that we want to read. Example. We want to read the 3 lower most bits.

So,

value = byte & 0b00000111. 

Should be clear now. . . .

We have also 2 additional important operations, and that is shifting. Since bits, depending on their position, have a different value, we need often to shift tehm to the correct position.

In your example, letS write the value 9 to the 4 upper most bits. What we need to do is:

  1. Delete any old stuff that is possibly thaer with masking
  2. Create value 9 and shift it to 4 positions to the right
  3. Delete the 4 lower bits of the shifted values
  4. OR the result over the target value
unsigned char value = 9;
value = value << 4;
value = value & 0b11110000;
Target = target | value;

Of course you can do all this in one statement.

Reading the 4 upper most values will be the reverse approach.

value = target & 0b11110000;
value = value >> 4;
value = value & 0b00001111;

by creating bit patterns ( a mask) you can influence all desired bits

CodePudding user response:

You have several way:

  • manual way, Do the bitwise operations manually, something like:

    struct S
    {
    private:
        std::byte getPage() const { return (data & 0xF0) >> 4; }
        void setPage(std::byte value) { return data = (data & 0x0F) | ((value & 0x0F) << 4); }
    
        bool getCtrl1() const { return data & 0x08; } // 1 << 3
        bool getCtrl2() const { return data & 0x04; } // 1 << 2
        bool getCtrl3() const { return data & 0x02; } // 1 << 1
        bool getCtrl4() const { return data & 0x01; } // 1 << 0
    
        void setCtrl1(bool b) { data = (data & ~0x08) | (b ? 0x08 : 0x00); }
        void setCtrl2(bool b) { data = (data & ~0x04) | (b ? 0x04 : 0x00); }
        void setCtrl3(bool b) { data = (data & ~0x02) | (b ? 0x02 : 0x00); }
        void setCtrl4(bool b) { data = (data & ~0x01) | (b ? 0x01 : 0x00); }
    
    private:
        std::byte data;
    };
    
  • use bit field:

    struct S
    {
         std::byte pages : 4;
         std::byte ctrl1 : 1;
         std::byte ctrl2 : 1;
         std::byte ctrl3 : 1;
         std::byte ctrl3 : 1;
    };
    

    (but no guaranty of order)

  • Related